対話型の Vite アプリでも、ブラウザーで CSS を生成する必要があるとは限りません。静的スタイルシートにすでにルールがある2つの class を、ボタンで切り替えられます。重要なのはインターフェースが変わるかどうかではなく、完全な class 名がいつ利用可能になるかです。
ソースにボタンの色が2種類あり、ビルド済み HTML には空のマウント先だけがあり、ブラウザーの初回描画では1つのボタンが表示される、クライアント描画のアプリを考えます。この3つの入力は同じアプリを表しますが、Master CSS に渡す class の集合は異なります。
このページの内容
#1つのアプリ、3つの入力
CSS エントリーも読み込んでいる既存の Vite セットアップから始めます。この小さな vanilla の例は両バリアントをソースに残し、JavaScript でボタンを作成します。
<div id="app"></div><script type="module" src="/src/main.js"></script>import './style.css'const tones = { blue: 'bg-blue', neutral: 'bg-neutral' }const button = document.createElement('button')let active = falsefunction update() { button.className = active ? tones.neutral : tones.blue button.textContent = active ? 'Selected' : 'Select'}button.addEventListener('click', () => { active = !active update()})update()document.getElementById('app').append(button)ソースには bg-blue と bg-neutral があります。HTML ファイルにはどちらもありません。JavaScript がまだボタンを作っていないためです。ブラウザーがエントリーモジュールを実行すると、接続されたボタンに bg-blue が付きます。クリックすると bg-neutral に変わります。
1つのアプリ、3つのclass集合
同じクライアント描画アプリに対する、選択肢となる生成入力です。classの変更は既存の静的CSSを再利用でき、空のHTMLマウント先は初期ボタンのルールを提供しません。
テキストによる説明
- ソース → 静的CSS. ボタンのソースにはbg-blueとbg-neutralの両方があります。静的モードは状態を選ぶ前に両ルールを生成します。
- ビルドHTML → 事前レンダリングCSS. 出力HTMLは空のアプリのマウント先だけを持ちます。ボタンのclassがないため、pre-renderモードはどちらのルールも生成しません。
- 接続済みDOM → runtime CSS. ブラウザーの初回描画でbg-blueのボタンが接続され、runtimeモードがそのルールを生成します。後からbg-neutralへ切り替えると、そのルールも生成します。
図は3つの生成戦略に渡す入力を比較しています。3段階の連続したビルド処理を示したり、全モードを同時に使うことを勧めたりするものではありません。
#静的 CSS でも変化するインターフェースに対応できる
既定の masterCSS() プラグイン設定では、スキャナーが src/main.js の両方の完全な文字列を見つけます。ボタンに同時に付くのは1つでも、生成スタイルシートには両方のルールが含まれます。クリックで変わるのは既存ルールのどちらが一致するかであり、Master CSS に CSS 生成を依頼するわけではありません。
サイズの選択、状態ラベル、ナビゲーションの選択など、有限の状態に適しています。マップには完全な class 文字列を残します。代わりに `bg-${tone}` を組み立てると、ソース上の根拠が失われます。スキャナーは補間式を実行して結果の候補を調べないためです。完全な class の扱いと明示的なソース例外はスキャンと pruningにまとめています。
CSS を使えることと、アプリが描画されることは別です。この例で JavaScript を無効にすると、静的スタイルシートは残りますが、ボタンは存在しません。ボタンを作るのはアプリのコードだからです。Master CSS の静的モードは、クライアント描画のアプリが JavaScript なしで動作することを約束しません。
#空のマウント先は描画済みのページではない
Vite の通常の本番ビルドは index.html を既定のエントリーとします。Master CSS の pre-render モードはビルドが出力する HTML を処理しますが、アプリのエントリーを実行してマウント先をボタンに変えることはしません。
masterCSS({ mode: 'pre-render' }) では、この例の HTML にボタンの class がないため、どちらの色の生成ルールもありません。後からブラウザーがボタンを作れますが、pre-render モードは不足ルールを生成する Master CSS runtime を配信しません。
pre-render モードは、ビルドが内容を持つ HTML を実際に出力する場合に役立ちます。HTML にすでに <button class="bg-blue">Select</button> があれば、Master CSS は青い class のルールを生成できます。neutral バリアントがクリック後にしか現れなければ、別の CSS ソースが必要です。HTML の生成をフレームワークが担う場合は、フレームワークのインテグレーションを使います。
#ブラウザーでの生成は接続済み class を追う
masterCSS({ mode: 'runtime' }) では、ランタイムが接続されたボタンを監視して青いルールを生成します。クリックで neutral の class が現れると、そのルールも生成します。最後の使用要素がなくなってもルールがキャッシュに残ることがあります。接続中の利用を追うことは、CSS が即座に削除される保証ではありません。
この方法は、ビジュアルエディターからの入力など、ブラウザーで初めて存在する完全な class 名に対応できます。一方、生成スタイルはランタイムの起動に依存します。上の有限マップなら、静的モードだけですでに両状態をその依存なしに扱えます。
#プログレッシブレンダリングが役立つ場面
プログレッシブモードは、出力 HTML から生成した CSS と、後から現れる class へのブラウザー対応を組み合わせます。HTML の境界は pre-render モードと同じです。空のマウント先からは初期ボタンのルールを得られません。その場合、アプリのコードがボタンを作った後で、ブラウザーがルールを生成する必要があります。
この組み合わせは、HTML が初期画面をすでに表し、追加の class が本当に後から現れる場合に役立ちます。初期生成 CSS はドキュメントとともに届き、ページの hydration マニフェストによって、ランタイムはエンジンを遅延しながら対応済みの class を追えます。マニフェスト外の class がエンジンを起動します。モード全体の比較、hydration、失敗条件はレンダリングモード Guideが管理します。
この仕組みが示すのは CSS を使えるタイミングです。描画時間の改善や総ダウンロード量の減少を示すものではありません。それらはアプリに依存し、測定が必要です。
#モードを変える前に入力を検証する
例を本番用にビルドし、出力 HTML と実行中の DOM を比較します。HTML には空のマウント先が残り、JavaScript 実行後の DOM にはボタンがあるはずです。静的モードでは、リンクされた生成スタイルシートに .bg-blue と .bg-neutral の両方があることを確認し、ボタンをクリックして両状態にスタイルが付くことを確かめます。
pre-render やプログレッシブモードを評価する場合は、レスポンスの style#master-css に実際のアプリ class とルールがあるか確認します。ブラウザーでの生成が初期の欠落を隠すことがあるので、実行中の DOM だけでなくレスポンスソースを見てください。開発時の動作だけでは本番配信を確認したことになりません。
ソースで見つかる class で目的を果たせるなら、静的モードを保ちます。別の入力を選ぶのは、ソースにはない情報をそこから得られる場合です。その情報を選んだライフサイクルが実際に提供するか検証してください。インストールは Vite Guide、レンダリングの契約はレンダリングモードにまとめています。

