1000コンポーネントでの`@reference` + `@apply`メモリ・パフォーマンス検証テストを追加

tailwindlabs/tailwindcss

Vue統合テストに1000コンポーネントを使ったシナリオを追加し、@reference@applyの組み合わせによるOOM問題やメモリリークが現バージョンで発生しないことを確認・継続保証する仕組みを整備しました。

背景

Discussion #16429では、複数のVueコンポーネントが@referenceでCSSファイルを参照しつつ@applyを使用する構成において、OOM(Out of Memory)やCSSサイズの肥大化が報告されていました。これらの報告は実際のプロダクション規模での利用を想定した懸念であり、単純なユニットテストでは検証しきれない問題です。

PR作成時点では現行コードでOOMを再現できなかったものの、問題が再発しないことを保証する自動テストが存在しなかったため、今後のリグレッション検出を目的として本テストが追加されました。

技術的な変更

integrations/vite/vue.test.tsに、1000コンポーネントを生成してビルドおよびHMRを検証する統合テストケースが追加されました。

コンポーネント生成ロジックは、Array.fromObject.fromEntriesを組み合わせてファイルシステムのエントリを動的に構築します。各コンポーネントは以下の構造を持ちます:

const VUE_COMPONENT_COUNT = 1_000

let vueComponentsWithReferences = Object.fromEntries(
  Array.from({ length: VUE_COMPONENT_COUNT }, (_, idx) => [
    `src/components/Component${idx}.vue`,
    html`
      <template>
        <div class="content-['component-${idx}']">Component ${idx}</div>
      </template>

      <style>
        @reference '../main.css';

        .component-${idx} {
          @apply text-red-500;
        }
      </style>
    `,
  ]),
)

各コンポーネントは以下の3つの要素を組み合わせています:

  • content-['component-N']というコンポーネント固有のユーティリティクラス(JITで個別生成される)
  • @reference '../main.css'によるメインスタイルシートへの参照
  • @apply text-red-500によるユーティリティの展開

さらに、1000コンポーネントを全てインポートしてマウントするApp.vue相当のエントリポイントも動的生成され、実際のビルドパイプライン全体を通じた検証が行われます。

ビルド結果として確認されたパフォーマンスは以下の通りです:

  • @reference + @applyあり:ビルド時間 3.17s、CSS出力 106.65 kB
  • @reference + @applyなし:ビルド時間 1.97s、CSS出力 106.61 kB

1000ファイルに@reference@applyを追加することで約1.2秒の増加が確認されましたが、CSSサイズの肥大化は発生していません。

設計判断

コンポーネント数を1000に固定する設計は、OOM報告が多数コンポーネントを持つプロジェクトで発生していたという背景に基づいています。単一コンポーネントのテストでは問題を再現できないため、実際の規模感を模倣した数値が採用されました。

また、各コンポーネントが固有のクラス名(component-N)を持つ構造にすることで、CSSの重複排除や誤った最適化によってテストが形骸化することを防いでいます。すべてのコンポーネントで同一のクラスを使い回す設計では、メモリやCSSサイズの増大を適切に検出できないためです。

HMRの検証についても言及されており、Vite開発サーバーを起動して1000回のファイル変更を施してもメモリが増加し続けないことをPR作成者が手動で確認しています。テストコードとして自動化されているのはプロダクションビルドのアサーションですが、HMR動作の健全性も本PRの検証スコープに含まれています。

まとめ

このテストは、報告されたOOMやCSSサイズ肥大化の問題が現行コードで発生しないことを確認するとともに、将来の変更でリグレッションが起きた際に即座に検出できる安全網として機能します。@reference@applyを多用する実際のVueプロジェクト構成をそのまま模倣したテストシナリオが整備されたことで、パフォーマンス特性の変化を継続的に追跡できるようになります。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
166b8848

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文(総論)→セクション群(背景・技術詳細・設計判断)→まとめ(結論)の3部構成が明確に適用されており、非常に分かりやすい構成です。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きシンタックスハイライト(```typescript:integrations/vite/vue.test.ts)やGitHubのDiscussion/PRへのリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

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

OOM、HMR、@reference、@applyといった専門用語を前提知識として使用しており、対象読者である専門エンジニアに適した技術レベルで記述されています。

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

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

各セクション、各パラグラフが要点から始まる構成になっており、非常に高い可読性を実現しています。1段落1トピックの原則も守られています。

Diff内容との照合 ✓ PASS

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

記事に引用されているコードブロックは、提供されたDiffの内容と完全に一致しており、ファイル名も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

OOM、リグレッション、HMRなど、PRの文脈で使われている技術用語を正確に使用しています。

説明の技術的正確性 ✓ PASS

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

テストの設計意図(1000コンポーネント、固有クラス名)に関する説明は技術的に妥当であり、PRの目的を的確に解説しています。

事実の突合 ✓ PASS

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

記事内の主張はすべてPRのDescriptionやDiffの内容に基づいており、根拠のない推測や創作(ハルシネーション)は見られません。

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

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

PR番号(#20055)、Discussion番号(#16429)、ビルド時間(3.17s, 1.97s)、CSSサイズ(106.65 kB, 106.61 kB)などの数値・固有名詞はすべて正確です。

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

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

記事のタイトルはPRの主題「Add Vue integration test with 1000 components」をより具体的に、かつ正確に表現しています。

外部知識の正確性 ✓ PASS

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

PR情報に記載のない、バージョンのサポート状況やリリース日程といった外部知識の追加はありません。

時間表現の正確性 ✓ PASS

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

PR内の「Right now」「in the future」といった時間軸を「PR作成時点」「今後」と正確に記事内で表現できています。