ブート時の一括コンパイルを計測する `compile.view_component` イベントの追加

viewcomponent/view_component

ViewComponentのEagerロード時の一括コンパイルが、compile.view_component という ActiveSupport::Notifications イベントとして計測できるようになりました。設定不要で常に発火するため、起動時のコンパイルコストを手軽に可視化できます。

背景

ViewComponentは既に render.view_component イベントによるレンダリング計測の仕組みを持っていましたが、ブート時の一括コンパイル(Eager Compilation)はこれまで計測の手段がありませんでした。config.eager_load = true の環境では、アプリケーション起動時に全コンポーネントの __vc_compile が一括実行されますが、その処理にどれだけ時間がかかっているかは外部から観察できない状態でした。

既存の render.view_component イベントは config.instrumentation_enabled = true が必要なオプトイン方式ですが、今回追加された compile.view_component は設定不要で、config.eager_load = true の場合に常に発火します。コンパイル計測はレンダリング計測とは異なりパフォーマンスへの影響が限定的であるため、常時有効化という判断が取られています。

技術的な変更

変更の核心は lib/view_component/engine.rbview_component.eager_load_actions イニシャライザに ActiveSupport::Notifications.instrument ブロックを追加した1点です。

変更前:

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
  end
end

変更後:

initializer "view_component.eager_load_actions" do
  ActiveSupport.on_load(:after_initialize) do
    if Rails.application.config.eager_load
      ActiveSupport::Notifications.instrument("compile.view_component") do
        ViewComponent::Base.descendants.each(&:__vc_compile)
      end
    end
  end
end

instrument ブロックで全コンポーネントの __vc_compile 呼び出しを囲むだけの最小限の変更です。購読側では以下のようにイベントを受け取れます:

ActiveSupport::Notifications.subscribe("compile.view_component") do |event|
  event.name     # => "compile.view_component"
  event.duration # => 123.45 (milliseconds)
end

テストは test/sandbox/test/instrumentation_test.rb に追加されました。ViewComponent::Engine.initializers から view_component.eager_load_actions を名前で取り出して直接実行する方式を採用しており、config.eager_load を一時的に true に切り替えた後、ViewComponent::CompileCache.invalidate! でキャッシュをクリアしてから検証しています。

設計判断

コンパイル全体を1つのイベントとして計測する粒度の選択が、この変更の核心的な設計判断です。

個々のコンポーネントごとにイベントを発火する設計も考えられますが、今回は全コンポーネントの一括コンパイルをまとめて1イベントとして扱っています。これはブート時の総コンパイルコストを把握するというユースケースに直接対応したものです。既存の render.view_component がリクエストごとの個別計測であるのに対し、compile.view_component はブート処理全体のコストを俯瞰するという異なる観測目的を持ちます。

また、オプトアウト不要の常時有効化は、コンパイルが eager_load = true 時のみ走るという前提から自然に導かれます。イベントが発火する条件が config.eager_load の真偽に完全に依存しており、それ以外の制御を加えないシンプルな実装となっています。

まとめ

compile.view_component イベントの追加により、ViewComponentのブート時コンパイルコストがActiveSupport::Notificationsの標準的なAPIで計測可能になりました。変更量は最小限ながら、既存の計測インフラを活用してデプロイ時のパフォーマンス観測に新たな軸を加えた変更です。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
1c8df05d

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の構成が記事全体と各セクションで明確に適用されています。リード文、背景、技術詳細、設計判断、まとめの各要素が適切に配置されています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きのシンタックスハイライト(```ruby:filepath)やPR番号のリンク記法([#2613](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

ViewComponentやRailsの内部実装に関する知識を前提としており、専門知識を持つエンジニアという対象読者に適合した内容です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落はトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られています。可読性が非常に高いです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されているコード(lib/view_component/engine.rbの変更、購読側の例)は、提供されたDiff情報と完全に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`eager compilation`、`ActiveSupport::Notifications`、`__vc_compile`といった技術用語が正確かつ適切な文脈で使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「`config.eager_load = true`の場合に発火する」という説明がDiffのif文で裏付けられるなど、すべての技術的説明が正確で論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

PRのDescriptionが存在しないにもかかわらず、記事の主張はすべてPR TitleとDiffの内容から裏付けられています。「設計判断」セクションはコードから論理的に導かれた妥当な解説であり、捏造ではありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2613)やイベント名(compile.view_component)などの固有名詞はすべて正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRのタイトル「Add compile.view_component ... event for eager compilation」の内容を正確に反映しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

既存の`render.view_component`イベントに関する言及は、今回の変更との対比を明確にするための適切な文脈説明であり、捏造された外部知識ではありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「〜できるようになりました」といった時間表現は、PRの内容と矛盾しておらず正確です。