Tôi nghe từ một số người lo ngại về việc tách view Rails lớn thành partial nhỏ: Render một partial thực sự tốn bao nhiêu thời gian? Có chi phí hiệu năng gọi partial lấn át lợi ích readability của code không?
Tôi chạy số liệu để đưa ra ví dụ so sánh partial rendering đơn giản với inline rendering, để chúng ta có thể thảo luận tradeoff sau. Đây là code benchmark, trong Rails app mới (với config.cache_classes = true):
<% 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 -%> <p>Hello!</p> Và kết quả (dùng Ruby 2.1 và Rails 4.0.2, trên Macbook Pro 15" Retina 2013):
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) Vậy, một partial render chạy trung bình khoảng 0.1ms trên máy nhanh. Nó chậm hơn render inline rất nhiều, nhưng đủ nhanh để khó nhận ra khi bạn còn có URL generation, Rails helper, và browser rendering time.
Tốc độ không phải là mọi thứ
Nếu hiệu năng render partial tồi tệ hơn nhiều, tôi vẫn có thể quyết định tách view lớn ra.
Có câu nói, Make It Work, Make It Right, Make It Fast. Khi bạn sửa view quá lớn, bạn đang cố thoát "Make it Work", và bạn không thể nhảy thẳng đến "Make it Fast." Bạn sẽ làm code kém maintainable, và có thể bỏ lỡ cơ hội refactor, dẫn đến cơ hội caching, dẫn đến lợi ích hiệu năng lớn hơn.
Bạn không biết cho đến khi đo
Bạn không phải tin số của tôi. Tôi khuyên bạn đừng! Thư viện Benchmark của Ruby cho công cụ đơn giản chạy benchmark riêng. Cũng có tool profile full stack, như New Relic và MiniProfiler. Tôi dùng cả ba khá thường xuyên trong công việc hàng ngày.
Khi profile, luôn profile ở production mode! Môi trường development Rails auto-reload class và view, hữu ích khi dev, nhưng sẽ giết số liệu hiệu năng.