網站導覽

搭配 Next.js 使用 Master CSS:何時選擇漸進式渲染

從預先渲染的 Next.js HTML 生成 CSS,在瀏覽器處理後續 class,並釐清動態 SSR 的適用邊界。

元件可能組合出原始碼中不存在完整字串的 class 名稱。如果 Next.js 在建置期間渲染該元件,最終 HTML 就會包含這個 class,即使來源掃描器無法推斷它。@master/css-next 的漸進式渲染會利用該 HTML 生成頁面 CSS,再由 Master CSS runtime 處理瀏覽器中後續出現的 classes。

靜態渲染仍是預設。完整 class 名稱能在原始碼中找到,且一般生成樣式表已符合需求時,請使用靜態模式。靜態或預先渲染頁面需要依最終標記生成 CSS,並支援後續 class 變更時,再選擇漸進式模式。

適用邊界是建置時的 HTML。 轉接器會處理 next build 的靜態與預先渲染輸出,不會處理請求時生成的動態 SSR 回應;在漸進式模式下,這些回應的生成規則依賴瀏覽器 runtime。

本頁內容

#為何使用最終 HTML

Next.js 的 Adapter API 會提供完成的建置輸出。@master/css-next 使用 onBuildComplete 掛鉤找出靜態與預先渲染 HTML,並將每份文件交給 Master CSS 伺服器渲染器。

此時,頁面已將版面、元件與內容組合成標記。Master CSS 可直接讀取文件中的 class 字串,不必推斷應用如何組合它們。只要 Next.js 在建置期間輸出其 HTML,這種方式就適合生成式標記與元件變體。


#Next.js 的漸進式渲染

交接流程分成三部分:

  1. Next.js 在 next build 期間產生靜態與預先渲染 HTML。
  2. Master CSS 讀取各文件,將生成規則插入 style#master-css。
  3. 瀏覽器 runtime 追蹤頁面 manifest 已涵蓋的 classes。未涵蓋的 class 會啟動引擎,引擎先驗證並採用相符規則,再生成新規則。

Next.js 漸進式模式的適用邊界

請分別驗證預先渲染頁面與動態路由。建置時 CSS 的涵蓋範圍,不代表請求時 SSR 也受到涵蓋。

文字說明
  1. 建置時 HTML. Next.js 輸出靜態或預先渲染 HTML。Master CSS 建置轉接器插入生成 CSS,並提供頁面 hydration 資料。
  2. 請求時 HTML. 動態 SSR 回應在建置轉接器結束後才產生。此整合不會預先渲染其生成 CSS;漸進式模式依賴瀏覽器 runtime 供應這些規則。

#CSS 與 runtime 的交接

含有生成規則的文件會收到外部頁面 hydration manifest。style 元素透過 data-master-css-hydration-manifest 指向它,讓 runtime 在延後載入引擎時仍可追蹤已涵蓋的 classes。引擎啟動後,會驗證並採用相符的 CSSOM 規則。runtime 需要生成頁面 manifest 以外的 class 時,才載入引擎。

行內 CSS 在交接前就能使用。manifest 用來支援後續規則管理,瀏覽器套用文件中既有 CSS 時並不需要它。完整傳遞與 hydration 行為請參閱渲染模式。


#驗證正式建置的交接

請依照 Next.js 安裝指南選擇漸進式模式並載入 CSS 入口。下方範例以該設定為前提;設定與轉接器組合選項集中在整合指南中。

請使用 Next.js 會在建置時預先渲染的頁面。將下一節的 <Badge tone="blue" /> 放入該頁面,再執行:

npm run buildnpm run start

檢查頁面的回應原始碼。style#master-css 應包含藍色標章的生成規則與 data-master-css-hydration-manifest 參照,並確認參照的資產可正常載入。不要只檢查即時 DOM,請檢查回應原始碼,否則 runtime 生成可能掩蓋建置時 CSS 缺漏。

接著,透過用戶端互動加入 <Badge tone="neutral" />。該 class 若不在頁面 manifest 中,就由瀏覽器生成補上缺少的規則。第二項觀察測試後續運作,初始回應則測試建置時涵蓋範圍。渲染模式說明 runtime 就緒與復原的邊界。


#來源掃描與渲染後的 classes

Master CSS 來源掃描需要完整 class 字串,不會求值元件插值。變體已預先確定時,適合使用包含所有完整 classes 的明確對照表。

漸進式渲染可改用預先渲染文件中實際出現的 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。前景 classes 分別解析為 color: var(--color-text-blue) 與 color: var(--color-text-neutral);背景 classes 則使用對應色彩的 10% 不透明度。只有藍色標章的頁面,初始生成 CSS 不需要 neutral 變體規則。neutral 標章之後才出現時,runtime 可生成其規則。

這項選擇以已渲染 HTML 的涵蓋範圍加上瀏覽器 runtime,取代來源導向的涵蓋範圍。有限的 class 對照表已能提供全部所需變體時,靜態模式仍然合適。


#頁面會有什麼變化

#CSS 可用時機

預先渲染的文件會在回應中帶有生成 CSS。這些規則不必等待 Master CSS runtime 啟動,就能套用到頁面。這讓 runtime 生成不再是這些樣式的前提,但不代表已實測證明首次繪製改善;圖片、字體、其他樣式表與指令碼仍會影響渲染。

#路由層級 CSS 輸出

每份文件都會收到自身 HTML 需要的生成 class 規則。共用原生樣式仍遵循應用的樣式表設定。預先渲染不代表頁面上每個樣式都是生成 utility,也不代表所有應用 CSS 都是路由專屬。

#保留 runtime 的彈性

僅在用戶端出現的元件與後續 class 變更仍受到支援。漸進式模式會增加 runtime 與 hydration manifest 的傳遞成本,選擇模式時應將其與較單純的靜態樣式表比較。

撰寫語法保持不變。模式改變的是讀取 classes 的時機,以及生成規則如何送達頁面。


#目前的適用邊界

只存在於請求時 SSR 回應中的路由,沒有完成的 HTML 可供建置時轉接器處理。漸進式模式不會為該回應提供預先渲染 CSS。代表性的動態路由應與預先渲染頁面分開測試,尤其是在 JavaScript 啟動前就必須有樣式的情況。

部署整合若也會處理建置輸出,請遵循轉接器組合設定,並檢查部署後的回應。本地建置正確,不代表後續轉接器保留了生成 CSS 與 manifest URL。


#何時維持靜態渲染

來源掃描能找到完整 class 字串時,請使用 Next.js 預設設定。靜態模式會產生樣式表,不需要 Master CSS 瀏覽器 runtime。請獨立驗證所選 bundler;安裝指南列出目前生成資產的限制與 Webpack 建置方式。互動元件仍可切換樣式表中已包含的 classes。

有明確需求時才選擇漸進式模式:根據最終建置時 HTML 生成 CSS,並由 runtime 支援新 classes。套用至整個應用之前,請同時驗證預先渲染頁面與動態路由。