diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9a79b86a3..31c1f7ac9 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,10 @@ nav_order: 6 ## main +* Add `compile.view_component` ActiveSupport::Notifications event for eager compilation at boot time. + + *Joel Hawksley*, *GitHub Copilot* + ## 4.7.0 * Fix stale content cache when slots are accessed before `render_in`. diff --git a/docs/guide/instrumentation.md b/docs/guide/instrumentation.md index 2a29ed12a..1a0709fc7 100644 --- a/docs/guide/instrumentation.md +++ b/docs/guide/instrumentation.md @@ -28,6 +28,20 @@ end _Note: Enabling instrumentation negatively impacts the performance of ViewComponent._ +## Compile instrumentation + +Since 4.8.0 +{: .label } + +ViewComponent also instruments eager compilation at boot time via the `compile.view_component` event. This event is always emitted (no configuration needed) when `config.eager_load` is `true`: + +```ruby +ActiveSupport::Notifications.subscribe("compile.view_component") do |event| + event.name # => "compile.view_component" + event.duration # => 123.45 (milliseconds) +end +``` + ## Viewing instrumentation sums in the browser developer tools When using `render.view_component` with `config.server_timing = true` (default in development) in Rails 7, the browser developer tools display the sum total timing information in Network > Timing under the key `render.view_component`. diff --git a/lib/view_component/engine.rb b/lib/view_component/engine.rb index ed70c912d..39a30ff34 100644 --- a/lib/view_component/engine.rb +++ b/lib/view_component/engine.rb @@ -79,7 +79,11 @@ class Engine < Rails::Engine # :nodoc: initializer "view_component.eager_load_actions" do ActiveSupport.on_load(:after_initialize) do - ViewComponent::Base.descendants.each(&:__vc_compile) if Rails.application.config.eager_load + if Rails.application.config.eager_load + ActiveSupport::Notifications.instrument("compile.view_component") do + ViewComponent::Base.descendants.each(&:__vc_compile) + end + end end end diff --git a/test/sandbox/test/instrumentation_test.rb b/test/sandbox/test/instrumentation_test.rb index ea8254620..29e60e4ce 100644 --- a/test/sandbox/test/instrumentation_test.rb +++ b/test/sandbox/test/instrumentation_test.rb @@ -32,4 +32,26 @@ def test_instrumentation_disabled assert_equal(events.size, 0) end end + + def test_compile_instrumentation + events = [] + subscriber = ActiveSupport::Notifications.subscribe("compile.view_component") do |*args| + events << ActiveSupport::Notifications::Event.new(*args) + end + + old_eager_load = Rails.application.config.eager_load + Rails.application.config.eager_load = true + + ViewComponent::CompileCache.invalidate! + + # Execute the same block that the view_component.eager_load_actions initializer registers + initializer = ViewComponent::Engine.initializers.find { |i| i.name == "view_component.eager_load_actions" } + initializer.run(Rails.application) + + assert_equal(1, events.size) + assert_equal("compile.view_component", events[0].name) + ensure + Rails.application.config.eager_load = old_eager_load + ActiveSupport::Notifications.unsubscribe(subscriber) + end end