渲染模式

瞭解 Nuxt 中可用的不同渲染模式。

Nuxt 支援不同的渲染模式:通用渲染客戶端渲染,還提供混合渲染以及在CDN 邊緣伺服器上渲染應用程式的可能性。

瀏覽器和伺服器都可以解釋 JavaScript 程式碼,將 Vue.js 元件轉換為 HTML 元素。這一步稱為渲染。Nuxt 支援通用客戶端渲染。這兩種方法各有優缺點,我們將在下文中介紹。

預設情況下,Nuxt 使用通用渲染來提供更好的使用者體驗、效能並最佳化搜尋引擎索引,但您可以在一行配置中切換渲染模式。

通用渲染

此步驟類似於 PHP 或 Ruby 應用程式執行的傳統伺服器端渲染。當瀏覽器請求啟用通用渲染的 URL 時,Nuxt 在伺服器環境中執行 JavaScript (Vue.js) 程式碼,並將完全渲染的 HTML 頁面返回給瀏覽器。如果頁面是預先生成的,Nuxt 也可以從快取中返回完全渲染的 HTML 頁面。與客戶端渲染不同,使用者可以立即獲得應用程式的全部初始內容。

HTML 文件下載後,瀏覽器會對其進行解釋,Vue.js 會接管該文件。先前在伺服器上執行的相同 JavaScript 程式碼現在在客戶端(瀏覽器)中再次在後臺執行,透過將其監聽器繫結到 HTML 來實現互動性(因此稱為通用渲染)。這被稱為啟用。當啟用完成後,頁面可以享受動態介面和頁面過渡等優勢。

通用渲染允許 Nuxt 應用程式提供快速的頁面載入時間,同時保留客戶端渲染的優勢。此外,由於內容已存在於 HTML 文件中,爬蟲可以直接索引,而無需額外開銷。

哪些是伺服器渲染,哪些是客戶端渲染?

在通用渲染模式下,Vue 檔案的哪些部分在伺服器和/或客戶端上執行是正常的問題。

app/app.vue
<script setup lang="ts">
const counter = ref(0) // executes in server and client environments

const handleClick = () => {
  counter.value++ // executes only in a client environment
}
</script>

<template>
  <div>
    <p>Count: {{ counter }}</p>
    <button @click="handleClick">
      Increment
    </button>
  </div>
</template>

在初始請求時,counter 引用在伺服器上初始化,因為它在 <p> 標籤內渲染。handleClick 的內容從未在此處執行。在瀏覽器中的啟用過程中,counter 引用會重新初始化。handleClick 最終將自身繫結到按鈕;因此可以合理地推斷 handleClick 的主體將始終在瀏覽器環境中執行。

中介軟體頁面在伺服器和客戶端啟用期間執行。外掛可以在伺服器、客戶端或兩者上渲染。元件也可以強制只在客戶端執行。可組合項工具函式根據其使用上下文進行渲染。

伺服器端渲染的優勢

  • 效能:使用者可以立即訪問頁面內容,因為瀏覽器顯示靜態內容的速度遠快於 JavaScript 生成的內容。同時,Nuxt 在啟用過程中保留了 Web 應用程式的互動性。
  • 搜尋引擎最佳化:通用渲染像經典伺服器應用程式一樣,將頁面的整個 HTML 內容傳遞給瀏覽器。網路爬蟲可以直接索引頁面內容,這使得通用渲染成為任何您想要快速索引的內容的絕佳選擇。

伺服器端渲染的缺點

  • 開發限制: 伺服器和瀏覽器環境不提供相同的 API,編寫可以在兩端無縫執行的程式碼可能很棘手。幸運的是,Nuxt 提供了指南和特定變數來幫助您確定一段程式碼的執行位置。
  • 成本: 伺服器需要執行才能動態渲染頁面。這增加了與任何傳統伺服器相同的每月成本。然而,由於通用渲染和瀏覽器在客戶端導航時接管,伺服器呼叫大大減少。透過利用邊緣側渲染可以降低成本。

通用渲染非常通用,幾乎適用於所有用例,尤其適用於任何面向內容的網站:部落格、營銷網站、作品集、電子商務網站和市場。

有關在沒有啟用不匹配的情況下編寫 Vue 程式碼的更多示例,請參見Vue 文件.
當匯入依賴於瀏覽器 API 並具有副作用的庫時,請確保匯入它的元件僅在客戶端呼叫。打包工具不會對包含副作用的模組的匯入進行 treeshake。

客戶端渲染

開箱即用,傳統的 Vue.js 應用程式在瀏覽器(或客戶端)中渲染。然後,在瀏覽器下載並解析所有包含建立當前介面的指令的 JavaScript 程式碼後,Vue.js 生成 HTML 元素。

客戶端渲染的優勢

  • 開發速度:當完全在客戶端工作時,我們無需擔心程式碼的伺服器相容性,例如,透過使用僅限瀏覽器的 API,如 window 物件。
  • 更便宜: 執行伺服器會增加基礎設施成本,因為您需要在支援 JavaScript 的平臺上執行。我們可以將純客戶端應用程式託管在任何帶有 HTML、CSS 和 JavaScript 檔案的靜態伺服器上。
  • 離線: 由於程式碼完全在瀏覽器中執行,因此在網際網路不可用時,它也能正常工作。

客戶端渲染的缺點

  • 效能:使用者必須等待瀏覽器下載、解析並執行 JavaScript 檔案。根據下載的網路和解析與執行的使用者裝置,這可能需要一些時間並影響使用者體驗。
  • 搜尋引擎最佳化:透過客戶端渲染交付內容的索引和更新比伺服器渲染的 HTML 文件花費更多時間。這與我們討論的效能缺陷有關,因為搜尋引擎爬蟲在第一次嘗試索引頁面時不會等待介面完全渲染。使用純客戶端渲染,您的內容需要更長時間才能在搜尋結果頁面中顯示和更新。

客戶端渲染是需要大量互動的Web 應用程式的不錯選擇,這些應用程式不需要索引或使用者經常訪問。它可以利用瀏覽器快取來跳過後續訪問的下載階段,例如 SaaS、後臺應用程式或線上遊戲

您可以在 nuxt.config.ts 中為 Nuxt 啟用純客戶端渲染。

nuxt.config.ts
export default defineNuxtConfig({
  ssr: false,
})
如果您確實使用 ssr: false,您還應該在 ~/spa-loading-template.html 中放置一個 HTML 檔案,其中包含您希望用於渲染載入螢幕的 HTML,該螢幕將在您的應用程式啟用之前渲染。
SPA 載入模板中閱讀更多內容。

部署靜態客戶端渲染應用程式

如果您使用 nuxt generatenuxt build --prerender 命令將您的應用程式部署到靜態主機,那麼預設情況下,Nuxt 會將每個頁面渲染為單獨的靜態 HTML 檔案。

如果您使用 nuxt generatenuxt build --prerender 命令預渲染您的應用程式,那麼您將無法使用任何伺服器端點,因為您的輸出資料夾中不包含伺服器。如果您需要伺服器功能,請改用 nuxt build

如果您純粹使用客戶端渲染,那麼這可能是不必要的。您可能只需要一個 index.html 檔案,以及 200.html404.html 回退檔案,您可以告訴您的靜態 Web 主機為所有請求提供這些檔案。

為了實現這一點,我們可以改變路由的預渲染方式。只需將其新增到您 nuxt.config.ts 中的您的鉤子

nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'prerender:routes' ({ routes }) {
      routes.clear() // Do not generate any routes (except the defaults)
    },
  },
})

這將生成三個檔案

  • index.html
  • 200.html
  • 404.html

200.html404.html 可能對您正在使用的託管服務提供商有用。

跳過客戶端回退生成

當預渲染客戶端渲染的應用程式時,Nuxt 預設會生成 index.html200.html404.html 檔案。但是,如果您需要阻止構建中生成任何(或所有)這些檔案,可以使用來自 Nitro'prerender:generate' 鉤子。

nuxt.config.ts
export default defineNuxtConfig({
  ssr: false,
  nitro: {
    hooks: {
      'prerender:generate' (route) {
        const routesToSkip = ['/index.html', '/200.html', '/404.html']
        if (routesToSkip.includes(route.route)) {
          route.skip = true
        }
      },
    },
  },
})

混合渲染

混合渲染允許透過路由規則為每個路由設定不同的快取規則,並決定伺服器應如何響應給定 URL 的新請求。

此前,Nuxt 應用程式和伺服器的每個路由/頁面都必須使用相同的渲染模式,即通用渲染或客戶端渲染。在各種情況下,有些頁面可以在構建時生成,而另一些則應該進行客戶端渲染。例如,考慮一個帶管理部分的網站。每個內容頁面都應主要為靜態並生成一次,但管理部分需要註冊並更像一個動態應用程式。

Nuxt 包含路由規則和混合渲染支援。使用路由規則,您可以為一組 Nuxt 路由定義規則,更改渲染模式或根據路由分配快取策略!

Nuxt 伺服器將自動註冊相應的中介軟體,並使用以下方法將路由包裝在快取處理程式中Nitro 快取層.

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // Homepage pre-rendered at build time
    '/': { prerender: true },
    // Products page generated on demand, revalidates in background, cached until API response changes
    '/products': { swr: true },
    // Product pages generated on demand, revalidates in background, cached for 1 hour (3600 seconds)
    '/products/**': { swr: 3600 },
    // Blog posts page generated on demand, revalidates in background, cached on CDN for 1 hour (3600 seconds)
    '/blog': { isr: 3600 },
    // Blog post page generated on demand once until next deployment, cached on CDN
    '/blog/**': { isr: true },
    // Admin dashboard renders only on client-side
    '/admin/**': { ssr: false },
    // Add cors headers on API routes
    '/api/**': { cors: true },
    // Redirects legacy urls
    '/old-page': { redirect: '/new-page' },
  },
})

路由規則

您可以使用的不同屬性如下

  • redirect: string - 定義伺服器端重定向。
  • ssr: boolean - 停用應用程式某些部分的 HTML 伺服器端渲染,並使用 ssr: false 使它們僅在瀏覽器中渲染
  • cors: boolean - 使用 cors: true 自動新增 CORS 標頭 - 您可以透過使用 headers 覆蓋來自定義輸出
  • headers: object - 為您網站的某些部分新增特定的標頭 - 例如,您的資產
  • swr: number | boolean - 將快取標頭新增到伺服器響應,並在伺服器或反向代理上快取它,快取時間可配置(TTL)。Nitro 的 node-server 預設能夠快取完整響應。當 TTL 過期時,將傳送快取的響應,同時頁面將在後臺重新生成。如果使用 true,則會新增 stale-while-revalidate 標頭,但不帶 MaxAge。
  • isr: number | boolean - 行為與 swr 相同,不同之處在於我們可以在支援此功能的平臺(目前是 Netlify 或 Vercel)上將響應新增到 CDN 快取中。如果使用 true,則內容在 CDN 內部會持續到下一次部署。
  • prerender: boolean - 在構建時預渲染路由,並將其作為靜態資產包含在構建中
  • noScripts: boolean - 停用網站某些部分的 Nuxt 指令碼和 JS 資源提示渲染。
  • appMiddleware: string | string[] | Record<string, boolean> - 允許您定義應該或不應該在應用程式的 Vue 應用程式部分(即,不是您的 Nitro 路由)的頁面路徑中執行的中介軟體

在可能的情況下,路由規則將自動應用於部署平臺的原生規則以獲得最佳效能(目前支援 Netlify 和 Vercel)。

請注意,在使用 nuxt generate 時,混合渲染不可用。

示例

Nuxt Vercel ISR

在 Vercel 上部署的具有混合渲染功能的 Nuxt 應用程式示例。

邊緣側渲染

邊緣側渲染 (ESR) 是 Nuxt 中引入的一項強大功能,它允許透過內容分發網路 (CDN) 的邊緣伺服器將 Nuxt 應用程式渲染到更靠近使用者的位置。透過利用 ESR,您可以確保提高效能並減少延遲,從而提供增強的使用者體驗。

透過 ESR,渲染過程被推到網路的“邊緣”——CDN 的邊緣伺服器。請注意,ESR 更多是一種部署目標,而非實際的渲染模式。

當請求頁面時,它不會一路傳送到原始伺服器,而是被最近的邊緣伺服器攔截。此伺服器生成頁面的 HTML 並將其傳送回用戶。此過程將資料傳輸的物理距離最小化,從而減少延遲並更快地載入頁面

邊緣側渲染之所以可能,得益於Nitro,為 Nuxt 提供動力的伺服器引擎。它為 Node.js、Deno、Cloudflare Workers 等提供跨平臺支援。

您可以利用 ESR 的當前平臺是

請注意,在使用邊緣側渲染和路由規則時,可以使用混合渲染

您可以瀏覽部署在上述某些平臺上的開源示例

Nuxt Todos Edge

一個帶有使用者身份驗證、SSR 和 SQLite 的待辦事項應用程式。

Atinotes

一個基於 Cloudflare KV 的可編輯網站,支援通用渲染。