There's a lot of information out there about Rails' partial, with some claiming it degrades performance, while others argue that in production environments the impact isn't significant. There are also views suggesting that using view_component can enhance performance, but again, opinions vary. I was unsure which information was accurate, so I decided to conduct some measurements.
Testing Methodology
- Output the same content using direct coding, partial, partial with collection, and view component
- Measure performance in a development environment
- Measure performance in a production environment
Environment Setup
$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]
$ rails -v
Rails 6.1.3.1
# Gemfile
gem "view_component", require: "view_component/engine"
$ bundle install
$ rails g controller samples vanilla partial partial_collection view_component
$ rails g model sample name:string
$ rails db:migrate
# app/controllers/samples_controller.rb
class SamplesController < ApplicationController
before_action :build_samples
def vanilla
end
def partial
end
def partial_collection
end
def view_component
end
def build_samples
@samples = Sample.all
end
end
# db/seed.rb
100.times do |n|
Sample.create!(name: "user#{n}")
end
$ rails db:seed
vanilla
# app/views/samples/vanilla.html.erb
<% @samples.each do |sample| %>
<p><%= sample.name %></p>
<% end %>
partial
$ touch app/views/samples/_hoge.html.erb
# app/views/samples/_hoge.html.erb
<p><%= hoge.name %></p>
app/views/samples/partial.html.erb
<% @samples.each do |sample| %>
<%= render 'hoge', hoge: sample %>
<% end %>
partial(collection)
# app/views/samples/partial.html.erb
<%= render partial: 'hoge', collection: @samples, as: 'hoge' %>
view_component
$ rails g component Hoge hoge
# app/components/hoge_component.rb
class HogeComponent < ViewComponent::Base
def initialize(hoge:)
@hoge = hoge
end
end
# app/components/hoge_component.html.erb
<p><%= @hoge.name %></p>
# app/views/samples/hoge_component.html.erb
<% @samples.each do |sample| %>
<%= render(HogeComponent.new(hoge: sample)) %>
<% end %>
https://github.com/nyshk97/partial-view-components
Measurements
Accessed samples/vanilla, samples/partial, and samples/view_component, and checked the following parts of the log.
Local Environment
Accessed each 5 times and recorded the median value.
Result | |
---|---|
vanilla | 8.7ms |
partial | 23.3ms |
partial_collection | 8.5ms |
view_component | 9.2ms |
Production
Accessed each 11 times and recorded the median value.
The server used was Heroku.
Result | |
---|---|
vanilla | 5.3ms |
partial | 10.7ms |
partial_collection | 4.45ms |
view_component | 5.55ms |
Summary and Thoughts
- In both local and production environments, using view_component with each loop offers about twice the performance compared to partial.
- Conversely, if calling partial 100 times only doubles the time, perhaps there's no need to be overly concerned with calling it 5 or 10 times?
- In this test, the same partial was called 100 times, but the result might differ if different partials are called.
- In both local and production environments, partial_collection performed better than direct coding.
- With direct coding, the execution is linear without considering the number of items. In contrast, using render collection seems to perform better in terms of string generation cost, as it counts the number of items first and then
Top comments (0)