資深前端工程師面試指南:Nuxt 3 生命週期與 SSR、CSR、SSG 渲染策略
在資深前端工程師的面試中,Nuxt 3 是一個熱門話題,尤其是其生命週期以及伺服器端渲染 (SSR)、客戶端渲染 (CSR) 和靜態生成 (SSG) 的應用場景。這些議題不僅考驗對框架的理解,還涉及架構設計、效能優化與 SEO 等實務能力。本文整合了 Nuxt 3 的生命週期與三種渲染方式的常見面試題目,提供深入解析、程式碼範例、場景選擇建議與潛在陷阱,幫助你在面試中展現專業能力,並為實際專案選擇合適的渲染策略。
一、Nuxt 3 生命週期深入解析
Nuxt 3 的生命週期涵蓋伺服器端與客戶端階段,結合 Vue 3 的 Composition API 和 Nitro 引擎(Nuxt 的伺服器引擎)。以下按執行順序解析,並針對面試提供實用範例。
1. 伺服器端生命週期(SSR 或混合模式)
伺服器端生命週期在 Nuxt 處理請求時執行,適用於 SSR 或混合模式。
(1) 伺服器啟動與初始化
- 觸發時機:伺服器啟動或收到請求。
- 關鍵點:Nuxt 載入
nuxt.config.ts
,初始化模組、插件與 middleware。Nitro 引擎啟動,處理伺服器端路由。 - 面試問題:如何在 Nuxt 中配置全域 middleware?
- 回答:
- 在
server/middleware/
或nuxt.config.ts
定義全域 middleware,用於日誌或請求攔截。 - 範例程式碼(server/middleware/log.ts):
export default defineEventHandler((event) => { console.log(`Request: ${event.node.req.url}`); });
- 實務:用於追蹤 API 請求或設定 CORS。陷阱:避免阻塞請求導致效能下降。
- 在
(2) 伺服器端 Middleware
- 觸發時機:請求到達路由前。
- 關鍵點:全域或頁面級 middleware,檢查權限或重導。
- 面試問題:如何使用 middleware 實現權限控制?
- 回答:
- 定義路由 middleware,檢查 cookie 或 token,導向登入頁。
- 範例程式碼(middleware/auth.ts):
export default defineNuxtRouteMiddleware((to, from) => { const user = useCookie('token'); if (!user.value && to.path !== '/login') { return navigateTo('/login'); } });
- 實務:搭配
@nuxtjs/auth-next
模組。陷阱:SSR 中避免使用客戶端專用 API(如window
)。
(3) 資料預取(useAsyncData / useFetch)
- 觸發時機:頁面渲染前。
- 關鍵點:
useAsyncData
和useFetch
預取資料,序列化後傳至客戶端。 - 面試問題:如何避免重複資料請求?
- 回答:
- 使用
key
參數快取資料,確保唯一性。 - 範例程式碼(pages/index.vue):
<script setup> const { data: posts } = await useFetch('/api/posts', { key: 'posts' }); </script>
- 實務:用於 API 呼叫或資料庫查詢。陷阱:重複 key 導致快取覆蓋。
- 使用
(4) 伺服器端渲染
- 觸發時機:生成 HTML。
- 關鍵點:Nuxt 使用 Vue 的伺服器渲染器,
useHead
配置 meta tags 提升 SEO。 - 面試問題:如何確保 SSR 的 SEO 效果?
- 回答:
- 使用
useHead
動態生成 meta,整合@nuxtjs/sitemap
。 - 範例程式碼:
<script setup> useHead({ title: 'Home', meta: [{ name: 'description', content: 'SSR page' }], }); </script>
- 實務:設置 canonical links 避免重複內容。陷阱:伺服器與客戶端 meta 不一致。
- 使用
(5) 伺服器回應
- 觸發時機:HTML 傳送至客戶端。
- 關鍵點:Nitro 回傳渲染結果與序列化資料。
2. 客戶端生命週期
客戶端生命週期在瀏覽器接收 HTML 後執行,涵蓋 hydration 和 Vue 組件邏輯。
(1) Hydration
- 觸發時機:客戶端載入 HTML。
- 關鍵點:Vue 將靜態 HTML 轉為響應式應用,恢復伺服器序列化資料。
- 面試問題:如何避免 hydration mismatch?
- 回答:
- 確保伺服器與客戶端邏輯一致,使用
onServerPrefetch
或process.client
。 - 範例程式碼:
<script setup> const time = ref(''); if (process.client) { time.value = new Date().toISOString(); } </script>
- 陷阱:條件渲染(如隨機數)導致不一致。
- 確保伺服器與客戶端邏輯一致,使用
(2) Vue 組件生命週期
- 觸發時機:組件創建、更新、銷毀。
- 關鍵點:使用 Composition API 的
onMounted
、onUnmounted
等。 - 範例程式碼:
<script setup> onMounted(() => { console.log('Client-side mounted'); }); </script>
(3) 客戶端專用資料獲取
- 觸發時機:客戶端渲染時。
- 關鍵點:
useFetch
設server: false
僅客戶端執行。 - 範例程式碼:
<script setup> const { data } = await useFetch('/api/user', { server: false }); </script>
(4) 客戶端插件
- 觸發時機:客戶端初始化。
- 範例程式碼(plugins/analytics.client.ts):
export default defineNuxtPlugin((nuxtApp) => { window.addEventListener('click', () => console.log('Track click')); });
3. Nuxt 鉤子(Hooks)
- 伺服器端鉤子:如
render:response
,用於自訂回應。 - 客戶端鉤子:如
page:finish
,用於頁面載入後邏輯。 - 範例:
export default defineNuxtPlugin((nuxtApp) => { nuxtApp.hook('page:finish', () => console.log('Page loaded')); });
二、伺服器端渲染 (SSR)、靜態生成 (SSG) 與客戶端渲染 (CSR)
選擇渲染方式影響 SEO、效能與開發複雜度。以下解析三者的原理、優缺點與場景。
1. 伺服器端渲染 (SSR)
定義:伺服器生成完整 HTML,客戶端 hydrate 為互動應用。Nuxt 3 預設 SSR。
流程:
- 伺服器執行 middleware 和
useFetch
,生成 HTML。 - 客戶端 hydrate,綁定事件。
優點: - SEO 友好:爬蟲可解析。
- 首屏快速:HTML 即時回傳。
- 動態內容:適合頻繁更新。
缺點: - 伺服器負載高。
- Hydration 增加客戶端計算。
場景:電商產品頁(動態庫存)、新聞網站(即時內容)。
面試問題:如何優化 SSR 負載?
回答: - 使用 Nitro 快取或 CDN(如 Cloudflare)。
- 範例(nuxt.config.ts):
export default defineNuxtConfig({ nitro: { compress: true, render: { cache: { maxAge: 3600 } }, }, });
2. 靜態生成 (SSG)
定義:建置時生成靜態 HTML,部署至 CDN。透過 nuxt generate
實現。
流程:
- 建置時爬取路由,生成 HTML。
- 客戶端直接載入靜態檔案,隨後 hydrate。
優點: - 高效能:CDN 傳遞快速。
- 低成本:無需伺服器。
- SEO 優秀:預生成 HTML。
缺點: - 不適合動態內容。
- 建置時間隨頁面增加而延長。
場景:部落格、公司官網、行銷頁面。
面試問題:如何在 SSG 中加入動態內容?
回答: - 客戶端用
useFetch
補充資料。 - 範例:
<script setup> const { data } = await useFetch('/api/comments', { server: false }); </script>
3. 客戶端渲染 (CSR)
定義:瀏覽器渲染 HTML,Nuxt 設 ssr: false
或頁面級 definePageMeta({ ssr: false })
。
流程:
- 載入空 HTML 和 JS bundle。
- Vue 執行渲染與資料獲取。
優點: - 開發簡單:無伺服器邏輯。
- 低伺服器成本:僅需靜態主機。
缺點: - SEO 差:爬蟲難解析。
- 首屏慢:需下載 JS。
場景:內部 dashboard、即時聊天應用。
面試問題:如何改善 CSR 首屏速度?
回答: - 使用 lazy loading 與 code-splitting。
- 範例:
<script setup> const LazyComponent = defineAsyncComponent(() => import('./HeavyComponent.vue')); </script>
三、實務應用與範例
1. SSR:電商產品頁
需求:動態庫存與 SEO。
<script setup>
useHead({
title: 'Product Page',
meta: [{ name: 'description', content: 'Dynamic product' }],
});
const route = useRoute();
const { data: product } = await useFetch(`/api/products/${route.params.id}`);
</script>
<template>
<div>
<h1>{{ product.name }}</h1>
<p>Stock: {{ product.stock }}</p>
</div>
</template>
2. SSG:部落格文章
需求:快速載入與 SEO。
<script setup>
useHead({
title: 'Blog Post',
meta: [{ name: 'description', content: 'Static content' }],
});
const { data: post } = await useAsyncData('post', () => $fetch('/api/posts/1'));
</script>
<template>
<article>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
</article>
</template>
3. CSR:管理 dashboard
需求:高互動,無 SEO。
<script setup>
definePageMeta({ ssr: false });
const { data: metrics } = await useFetch('/api/metrics', { server: false });
</script>
<template>
<div>
<h1>Dashboard</h1>
<div v-if="metrics">{{ metrics.summary }}</div>
</div>
</template>
四、潛在陷阱與最佳實踐
SSR 陷阱:
- Hydration mismatch:伺服器與客戶端渲染不一致。
- 解決:使用
onServerPrefetch
或process.client
。 - 範例:
<script setup> const time = ref(''); onServerPrefetch(() => { time.value = new Date().toISOString(); }); </script>
SSG 陷阱:
- 建置時間長:過多動態路由。
- 解決:限制 prerender 路由或使用增量靜態生成 (ISG)。
CSR 陷阱:
- SEO 問題:動態內容無法爬取。
- 解決:混合 SSR 頁面(如首頁)。
最佳實踐:
- 混合模式:頁面級配置(如首頁 SSR,dashboard CSR)。
- 快取:Nitro 記憶體快取或 CDN。
- 監控:Lighthouse 分析首屏與 SEO。
五、模擬面試問題與回答
問題:如何決定使用 SSR、SSG 或 CSR?
回答:依 SEO、動態性與效能需求選擇。電商用 SSR 確保動態更新;部落格用 SSG 提升速度;內部工具用 CSR 簡化開發。問題:如何在 SSR 中處理 API 失敗?
回答:- 使用
useFetch
的 error 屬性,提供 fallback 或錯誤頁。 - 範例:
<script setup> const { data, error } = await useFetch('/api/data'); if (error.value) { throw createError({ statusCode: 500, message: 'API Failed' }); } </script>
- 使用
問題:如何在 Nuxt 生命週期中優化資料預取?
回答:- 使用
useAsyncData
快取,設定唯一 key,減少重複請求。 - 範例:
<script setup> const { data } = await useAsyncData('unique-key', () => $fetch('/api/data')); </script>
- 使用
六、總結
Nuxt 3 的生命週期整合伺服器端與客戶端,提供 middleware、資料預取與鉤子等工具,支援 SSR、SSG 和 CSR 三種渲染方式。SSR 適合動態內容與 SEO,SSG 適合靜態網站,CSR 適合互動應用。資深工程師應熟練配置混合模式,優化效能與 SEO,並避免 hydration mismatch 等陷阱。面試時,結合實務案例(如電商或 dashboard)展示技術深度,將大大提升說服力。
推薦資源:
- Nuxt 3 官方文件:https://nuxt.com/docs
- Nitro 引擎:https://nitro.unjs.io/
- Vue 3 伺服器渲染:https://vuejs.org/guide/scaling-up/ssr.html
沒有留言:
張貼留言