diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ce25cf2d3..88560fba8 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,10 @@ nav_order: 6 ## main +* Measure cache digest precomputation in the boot benchmark by disabling class reloading in the benchmark app and having each generated component render another. + + *Joel Hawksley* + * Add a CI performance check that fails a pull request when any benchmark scenario's component/partial render-time ratio, or ViewComponent's share of app boot time, regresses by more than 5% against the base branch on Rails 8.1 or Rails main. *Joel Hawksley* diff --git a/performance/boot.rb b/performance/boot.rb index c8a76c1a6..c587ae851 100644 --- a/performance/boot.rb +++ b/performance/boot.rb @@ -32,6 +32,7 @@ class BootApp < Rails::Application config.root = ARGV.fetch(0) config.load_defaults Rails::VERSION::STRING.to_f + config.cache_classes = true config.eager_load = true config.secret_key_base = "performance" config.logger = Logger.new(nil) diff --git a/performance/measure.rb b/performance/measure.rb index b1e8ff9c1..873af1033 100755 --- a/performance/measure.rb +++ b/performance/measure.rb @@ -121,7 +121,17 @@ class BenchmarksController < ActionController::Base components = File.join(root, "app", "components") FileUtils.mkdir_p(components) + # Each component renders another, so boot also discovers cache digest dependencies. + render_call = lambda do |i| + case i % 3 + when 0 then "render Sidecar#{i}Component.new(name: 'x')" + when 1 then "render(Inline#{i}Component.new) { 'x' }" + else "render Slots#{i}Component.new" + end + end + Integer(ENV.fetch("BOOT_COMPONENTS", 300)).times do |i| + rendered = render_call.call(i.zero? ? 1 : (i - 1) / 2) case i % 3 when 0 File.write(File.join(components, "sidecar#{i}_component.rb"), <<~RUBY) @@ -131,11 +141,11 @@ def initialize(name:) end end RUBY - File.write(File.join(components, "sidecar#{i}_component.html.erb"), "

<%= @name %>

\n") + File.write(File.join(components, "sidecar#{i}_component.html.erb"), "

<%= @name %>

<%= #{rendered} %>\n") when 1 File.write(File.join(components, "inline#{i}_component.rb"), <<~RUBY) class Inline#{i}Component < ViewComponent::Base - erb_template "

<%= content %>

" + erb_template "

<%= content %>

<%= #{rendered} %>" end RUBY else @@ -145,7 +155,7 @@ class Slots#{i}Component < ViewComponent::Base renders_many :items end RUBY - File.write(File.join(components, "slots#{i}_component.html.erb"), "<%= header %><% items.each do |item| %><%= item %><% end %>\n") + File.write(File.join(components, "slots#{i}_component.html.erb"), "<%= header %><% items.each do |item| %><%= item %><% end %><%= #{rendered} %>\n") end end