ナビゲーション

Next.jsでMaster CSS:プログレッシブレンダリングを選ぶとき

事前レンダリング済みのNext.js HTMLからCSSを生成し、後から現れるclassをブラウザーで処理する仕組みと、動的SSRとの境界を説明します。

コンポーネントは、ソースに完全な文字列として存在しない class 名を組み立てられます。Next.js がビルド中にそのコンポーネントを描画すれば、ソーススキャナーが推測できなくても、完成した HTML には class が含まれます。@master/css-next のプログレッシブレンダリングは、この HTML からページの CSS を生成し、以後ブラウザーで現れる class を Master CSS runtime に任せます。

既定は引き続き静的レンダリングです。完全な class 名をソースで確認でき、通常の生成スタイルシートで要件を満たせるなら、それを使います。静的ページや事前レンダリングしたページで最終マークアップに基づく CSS と、その後の class 変更へのランタイム対応が必要なら、プログレッシブモードを選びます。

境界はビルド時の HTML です。 アダプターは next build の静的出力と事前レンダリング出力を処理します。リクエスト時に生成される動的 SSR レスポンスは処理しません。プログレッシブモードでは、そのようなレスポンスの生成ルールはブラウザーのランタイムに依存します。

このページの内容

#完成した HTML を使う理由

Next.js の Adapter API は、完成したビルド出力を公開します。@master/css-next は onBuildComplete フックで静的・事前レンダリング済みの HTML を見つけ、各ドキュメントを Master CSS のサーバーレンダラーへ渡します。

この時点でページはすでにレイアウト、コンポーネント、内容をマークアップへまとめています。Master CSS は、アプリがどのように組み立てたかを推測せず、ドキュメント内の class 文字列を読み取れます。Next.js がビルド中にその HTML を出力するなら、生成されたマークアップやコンポーネントのバリアントに役立ちます。


#Next.js のプログレッシブレンダリング

引き継ぎは3つの部分で構成されます。

  1. Next.js が next build 中に静的・事前レンダリング済み HTML を出力します。
  2. Master CSS が各ドキュメントを読み、生成ルールを style#master-css に挿入します。
  3. ブラウザーのランタイムはページマニフェストがすでに扱う class を追跡します。未対応の class が現れるとエンジンが起動し、新しいルールを生成する前に一致する既存ルールを検証して採用します。

Next.jsのプログレッシブモードの境界

事前レンダリングページと動的ルートを別々に検証します。ビルド時のCSS網羅性は、リクエスト時SSRの網羅性を示しません。

テキストによる説明
  1. ビルド時HTML. Next.jsが静的・事前レンダリング済みHTMLを出力します。Master CSSのビルドアダプターが生成CSSを挿入し、ページのhydrationデータを提供します。
  2. リクエスト時HTML. 動的SSRレスポンスはビルドアダプターの終了後に作られます。このインテグレーションはその生成CSSを事前レンダリングせず、プログレッシブモードではブラウザーのランタイムに依存します。

#CSS とランタイムの引き継ぎ

生成ルールを持つドキュメントには、外部のページ hydration マニフェストを配信します。style 要素が data-master-css-hydration-manifest でそれを参照するため、ランタイムはエンジンを遅延したまま対応済みの class を追跡できます。エンジンが起動すると、一致する CSSOM ルールを検証して採用します。ページマニフェスト外の class を生成する必要があるとき、ランタイムがエンジンを読み込みます。

インライン CSS は、この引き継ぎ前から利用できます。マニフェストは継続的なルール管理を支えるもので、ドキュメントにすでにある CSS をブラウザーが適用するための必須条件ではありません。配信と hydration の全体はレンダリングモードを参照してください。


#本番ビルドの引き継ぎを検証する

Next.js インストールガイドに従い、プログレッシブモードを選んで CSS エントリーを読み込みます。以下はそのセットアップが前提です。設定とアダプターの組み合わせに関する選択肢はインテグレーションガイドにまとめます。

Next.js がビルド中に事前レンダリングするページを使います。次の節の <Badge tone="blue" /> をそのページに置き、次を実行します。

npm run buildnpm run start

ページのレスポンスソースを調べます。style#master-css には青いバッジの生成ルールと data-master-css-hydration-manifest の参照が含まれるはずです。参照先のアセットが読み込めることも確認します。実行中の DOM だけでなくレスポンスソースを使ってください。ランタイム生成が、ビルド時の CSS の欠落を隠すことがあるためです。

次に、クライアントの操作で <Badge tone="neutral" /> を追加します。その class がページマニフェスト外なら、ブラウザーでの生成が不足するルールを補います。この2つ目の確認は継続動作、最初のレスポンスはビルド時の網羅性を検証します。ランタイムの準備完了と復旧の境界はレンダリングモードを参照してください。


#ソーススキャンと描画後の class

Master CSS のソーススキャンには完全な class 文字列が必要です。コンポーネントの補間式は評価しません。バリアントが事前に分かる場合は、すべての完全な class を含む明示的なマップが適しています。

プログレッシブレンダリングでは、代わりに事前レンダリング済みドキュメントに現れる class 名を使えます。次のコンポーネントを考えます。

Badge.tsx
export function Badge({ tone }: {  tone: 'blue' | 'neutral'}) {  return (    <span className={`px-xs py-3xs r-sm bg-${tone}/.1 fg-text-${tone}`}>      New    </span>  )}

<Badge tone="blue" /> を描画すると、次のようになります。

blue.html
<span class="px-xs py-3xs r-sm bg-blue/.1 fg-text-blue">New</span>

<Badge tone="neutral" /> を描画すると、次のようになります。

neutral.html
<span class="px-xs py-3xs r-sm bg-neutral/.1 fg-text-neutral">New</span>

ビルド時の HTML にどちらかのバッジがあれば、アダプターは実際の class 一覧に対応する CSS を生成します。前景の class はそれぞれ color: var(--color-text-blue) と color: var(--color-text-neutral) へ解決され、背景の class は対応する色を不透明度10%で使います。青いバッジだけのページでは、初期生成 CSS に neutral バリアントのルールは不要です。neutral のバッジが後で現れれば、ランタイムがそのルールを生成できます。

この選択は、ソースに基づく網羅性を、描画済み HTML の網羅性とブラウザーのランタイムへ置き換えるものです。有限の class マップですべての必要なバリアントを表せるなら、静的モードが引き続き適しています。


#ページに生じる変化

#CSS を使えるタイミング

事前レンダリング済みドキュメントは、レスポンスに生成 CSS を含みます。Master CSS runtime の起動を待たずに、それらのルールでページを装飾できます。つまり、そのスタイルにはランタイム生成が前提でなくなります。ただし、初回描画の改善を測定で証明するものではありません。画像、フォント、他のスタイルシート、スクリプトも描画に影響します。

#ルート単位の CSS 出力

各ドキュメントは、自身の HTML が必要とする生成 class ルールを受け取ります。共通のネイティブスタイルは引き続きアプリのスタイルシート構成に従います。事前レンダリングは、ページ上のすべてのスタイルが生成ユーティリティであることや、すべてのアプリ CSS がルート固有であることを意味しません。

#ランタイムの柔軟性を保つ

クライアント専用コンポーネントや後からの class 変更も引き続き対応します。プログレッシブモードではランタイムと hydration マニフェストの配信が加わるため、モードを選ぶ際はその負担を、より単純な静的スタイルシートと比較してください。

記述する構文は変わりません。変わるのは class を読み取るタイミングと、生成ルールをページへ届ける方法です。


#現在の境界

リクエスト時の SSR レスポンスとしてだけ存在するルートには、ビルド時アダプターが処理できる完成済み HTML がありません。プログレッシブモードは、そのレスポンスへ事前レンダリング CSS を提供しません。特に JavaScript 起動前のスタイルが要件なら、代表的な動的ルートを事前レンダリングページとは別に検証してください。

デプロイ用インテグレーションもビルド出力を処理する場合は、アダプターの組み合わせ設定に従い、デプロイ済みのレスポンスも確認します。ローカルビルドが正しくても、後段のアダプターが生成 CSS とマニフェスト URL を保ったとは限りません。


#静的レンダリングを維持する場合

ソーススキャンで完全な class 文字列を見つけられるなら、Next.js の既定セットアップを使います。静的モードは Master CSS のブラウザーランタイムなしでスタイルシートを出力します。選んだバンドラーは個別に検証してください。インストールガイドに、現在の生成アセットの制約と Webpack のビルド手順があります。対話型コンポーネントでも、そのスタイルシートにすでにある class 間を切り替えられます。

最終的なビルド時 HTML に基づく CSS と、新しい class へのランタイム対応という具体的な必要がある場合に、プログレッシブモードを選びます。アプリ全体へ適用する前に、事前レンダリングページと動的ルートの両方を検証してください。