Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Rails 파셜(Partial) 렌더링, 실제로 얼마나 시간이 걸릴까?

대형 Rails 뷰를 작은 파셜(partial)로 분리하는 것을 주저하는 분들에게서 종종 이런 질문을 받습니다. 파셜 렌더링에는 실제로 얼마나 시간이 걸릴까? 파셜 호출이 성능에 미치는 영향이 코드 가독성의 이점보다 커지지는 않을까?

이 질문에 답하기 위해 간단한 파셜 렌더링과 인라인 렌더링의 성능을 비교하는 벤치마크를 직접 돌려봤습니다. 결과를 바탕으로 두 방식 사이의 트레이드오프를 함께 살펴보겠습니다. 아래는 새로 생성한 Rails 앱(config.cache_classes = true 설정)에서 사용한 벤치마크 코드입니다.

app/views/test/show.html.erb
<% require 'benchmark'
   Benchmark.bmbm do |x|
     x.report "inline" do
       10000.times do -%>
         <p>Hello!</p>
    <% end
     end
     x.report "partial" do
       10000.times do -%>
         <%= render partial: "hello" %>
    <% end
     end-%>
<% end -%>
app/views/test/_hello.html.erb
<p>Hello!</p>

측정 환경은 Ruby 2.1, Rails 4.0.2, 2013년형 15인치 Retina MacBook Pro입니다. 결과는 다음과 같습니다.

Rehearsal -------------------------------------------
inline    0.010000   0.000000   0.010000 (  0.007045)
partial   0.970000   0.090000   1.060000 (  1.050433)
---------------------------------- total: 1.070000sec

              user     system      total        real
inline    0.010000   0.000000   0.010000 (  0.005529)
partial   0.920000   0.070000   0.990000 (  0.997491)

결과를 해석해 보면, 빠른 머신 기준으로 파셜 렌더링 한 번은 평균 약 0.1ms가 소요됩니다. 인라인 렌더링보다는 확실히 느리지만, URL 생성, Rails 헬퍼 호출, 브라우저 렌더링 시간 등 다른 요소들까지 고려하면 사실상 체감하기 어려운 수준입니다.

속도가 전부는 아니다

흥미로운 점은, 설령 파셜 렌더링 성능이 지금보다 훨씬 나빴다 하더라도 저는 여전히 거대한 뷰를 분리하기로 결정했을 것이라는 사실입니다.

소프트웨어 개발에는 "동작하게 만들고(Make It Work), 올바르게 만들고(Make It Right), 빠르게 만들어라(Make It Fast)"라는 유명한 격언이 있습니다. 너무 큰 뷰를 다듬으려는 시점에서 우리는 '동작하게 만들기' 단계를 벗어나려는 것이지, 곧바로 '빠르게 만들기' 단계로 건너뛸 수는 없습니다. 순서를 무시하고 성능만 쫓으면 코드의 유지보수성이 떨어질 뿐 아니라 리팩토링 기회를 놓치게 됩니다. 그런데 이 리팩토링이야말로 캐싱 적용의 출발점이 되고, 캐싱은 파셜 분리 비용보다 훨씬 큰 성능 향상을 가져다줄 수 있습니다.

측정하기 전까지는 알 수 없다

물론 제가 제시한 수치를 그대로 믿으실 필요는 없습니다. 오히려 직접 확인해 보시길 권합니다! Ruby의 Benchmark 라이브러리는 누구나 손쉽게 벤치마크를 작성할 수 있는 도구를 제공합니다. 여기에 더해 New Relic이나 MiniProfiler처럼 애플리케이션 전체 스택을 프로파일링할 수 있는 도구들도 활용해 보세요. 저 역시 일상적인 업무에서 이 세 가지 도구를 모두 자주 사용하고 있습니다.

마지막으로 한 가지 중요한 팁을 드리자면, 프로파일링은 반드시 프로덕션 모드에서 진행해야 합니다. Rails 개발 환경은 클래스와 뷰를 매 요청마다 자동으로 다시 로드하는데, 이 기능은 개발 중에는 편리하지만 성능 측정 결과를 완전히 왜곡해 버립니다.