渲染模式
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 檔案的哪些部分在伺服器和/或客戶端上執行是正常的問題。
<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.js 應用程式在瀏覽器(或客戶端)中渲染。然後,在瀏覽器下載並解析所有包含建立當前介面的指令的 JavaScript 程式碼後,Vue.js 生成 HTML 元素。
客戶端渲染的優勢
- 開發速度:當完全在客戶端工作時,我們無需擔心程式碼的伺服器相容性,例如,透過使用僅限瀏覽器的 API,如
window
物件。 - 更便宜: 執行伺服器會增加基礎設施成本,因為您需要在支援 JavaScript 的平臺上執行。我們可以將純客戶端應用程式託管在任何帶有 HTML、CSS 和 JavaScript 檔案的靜態伺服器上。
- 離線: 由於程式碼完全在瀏覽器中執行,因此在網際網路不可用時,它也能正常工作。
客戶端渲染的缺點
- 效能:使用者必須等待瀏覽器下載、解析並執行 JavaScript 檔案。根據下載的網路和解析與執行的使用者裝置,這可能需要一些時間並影響使用者體驗。
- 搜尋引擎最佳化:透過客戶端渲染交付內容的索引和更新比伺服器渲染的 HTML 文件花費更多時間。這與我們討論的效能缺陷有關,因為搜尋引擎爬蟲在第一次嘗試索引頁面時不會等待介面完全渲染。使用純客戶端渲染,您的內容需要更長時間才能在搜尋結果頁面中顯示和更新。
客戶端渲染是需要大量互動的Web 應用程式的不錯選擇,這些應用程式不需要索引或使用者經常訪問。它可以利用瀏覽器快取來跳過後續訪問的下載階段,例如 SaaS、後臺應用程式或線上遊戲。
您可以在 nuxt.config.ts
中為 Nuxt 啟用純客戶端渲染。
export default defineNuxtConfig({
ssr: false,
})
ssr: false
,您還應該在 ~/spa-loading-template.html
中放置一個 HTML 檔案,其中包含您希望用於渲染載入螢幕的 HTML,該螢幕將在您的應用程式啟用之前渲染。部署靜態客戶端渲染應用程式
如果您使用 nuxt generate
或 nuxt build --prerender
命令將您的應用程式部署到靜態主機,那麼預設情況下,Nuxt 會將每個頁面渲染為單獨的靜態 HTML 檔案。
nuxt generate
或 nuxt build --prerender
命令預渲染您的應用程式,那麼您將無法使用任何伺服器端點,因為您的輸出資料夾中不包含伺服器。如果您需要伺服器功能,請改用 nuxt build
。如果您純粹使用客戶端渲染,那麼這可能是不必要的。您可能只需要一個 index.html
檔案,以及 200.html
和 404.html
回退檔案,您可以告訴您的靜態 Web 主機為所有請求提供這些檔案。
為了實現這一點,我們可以改變路由的預渲染方式。只需將其新增到您 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.html
和 404.html
可能對您正在使用的託管服務提供商有用。
跳過客戶端回退生成
當預渲染客戶端渲染的應用程式時,Nuxt 預設會生成 index.html
、200.html
和 404.html
檔案。但是,如果您需要阻止構建中生成任何(或所有)這些檔案,可以使用來自 Nitro 的 'prerender:generate'
鉤子。
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 快取層.
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
時,混合渲染不可用。示例
邊緣側渲染
邊緣側渲染 (ESR) 是 Nuxt 中引入的一項強大功能,它允許透過內容分發網路 (CDN) 的邊緣伺服器將 Nuxt 應用程式渲染到更靠近使用者的位置。透過利用 ESR,您可以確保提高效能並減少延遲,從而提供增強的使用者體驗。
透過 ESR,渲染過程被推到網路的“邊緣”——CDN 的邊緣伺服器。請注意,ESR 更多是一種部署目標,而非實際的渲染模式。
當請求頁面時,它不會一路傳送到原始伺服器,而是被最近的邊緣伺服器攔截。此伺服器生成頁面的 HTML 並將其傳送回用戶。此過程將資料傳輸的物理距離最小化,從而減少延遲並更快地載入頁面。
邊緣側渲染之所以可能,得益於Nitro,為 Nuxt 提供動力的伺服器引擎。它為 Node.js、Deno、Cloudflare Workers 等提供跨平臺支援。
您可以利用 ESR 的當前平臺是
- Cloudflare Pages使用 git 整合和
nuxt build
命令實現零配置 - Vercel Edge Functions使用
nuxt build
命令和NITRO_PRESET=vercel-edge
環境變數 - Netlify Edge Functions使用
nuxt build
命令和NITRO_PRESET=netlify-edge
環境變數
請注意,在使用邊緣側渲染和路由規則時,可以使用混合渲染。
您可以瀏覽部署在上述某些平臺上的開源示例