題幹與適用場景
內容頁包含導覽、正文、推薦、留言與個人化模組。正文應盡快可見,慢模組不能阻塞首位元組,也不能讓單一服務故障拖垮整頁。請設計基於 Suspense 的串流 SSR,說明伺服器如何傳送 shell、邊界如何逐塊完成、失敗如何降級,以及客戶端腳本載入後如何恢復互動。
React 文件說明,串流渲染可以先傳送 shell 與 fallback,再在邊界完成後替換內容;題目考察候選人能否把機制落成可控的逾時、錯誤、快取與監控方案。
面試官考察點
重點包括穩定 shell 與非同步邊界的切分、資料請求去重、邊界逾時、伺服器錯誤處理、客戶端重試、快取變體、取消請求、可及性與 Core Web Vitals。還要說明哪些內容必須同步完成,哪些內容適合延遲。
回答前需要釐清的問題
- 首屏目標是 TTFB、LCP 還是可互動時間,各自預算是多少?
- 正文、推薦、留言與個人化資料的可用性等級與隱私邊界是什麼?
- 頁面是否經過 CDN 快取,使用者、地區與實驗分流會產生哪些變體?
- 慢模組失敗時顯示空狀態、舊快取還是重試按鈕?
- 客戶端 JavaScript 失敗時,哪些功能仍必須可用?
30 秒回答框架
「先傳送不依賴慢資料的可及 shell,把推薦、留言與個人化拆成有明確預算的 Suspense 邊界。每個邊界都有伺服器逾時、可觀測錯誤與可接受 fallback;失敗只影響該區塊。回應結束後客戶端接管重試與互動。快取只快取安全的公共片段,監控 TTFB、LCP、INP、錯誤率與邊界耗時。」
分步驟深入解答
第一步:切分 shell 與邊界
同步完成路由、標題、正文骨架與主要語意結構;將推薦、留言與個人化拆成獨立邊界。邊界應對應使用者能理解的區域,避免一個邊界同時包含多個互不相關的遠端依賴。
shell: navigation + heading + article outline
boundary A: recommendations, budget 300 ms
boundary B: comments, budget 500 ms
boundary C: personalized actions, private and uncached每個邊界的 fallback 保留標題、尺寸與語意,防止完成時發生版面位移;不要為追求更多並行而把頁面切成難以理解的碎片。
第二步:建立串流回應與取消策略
使用框架提供的串流伺服器端渲染 API,讓 shell 先進入回應,再讓邊界隨資料完成。伺服器請求要攜帶請求級 deadline;逾時後停止遠端呼叫並輸出可接受的 fallback,客戶端不應繼續等待已取消的伺服器任務。
記錄每個邊界的開始、完成、逾時與錯誤事件。客戶端斷線時取消尚未完成的 fetch,避免使用者離開後繼續消耗資料庫或推薦服務資源。
第三步:處理伺服器與客戶端錯誤
伺服器邊界錯誤應被隔離到對應 fallback,保留 shell 與其他已完成內容。錯誤需要帶穩定的邊界識別與請求追蹤 ID,但使用者文案只說明內容暫時無法使用。
客戶端載入後,允許對可重試邊界發起帶退避的請求;重試必須有次數上限、冪等條件與取消入口。客戶端腳本載入失敗時,正文、連結與表單等核心路徑仍應保持可用。
第四步:設計快取邊界
公共正文與不含使用者資料的模組可以按路由、語言、地區與內容版本建立快取鍵。個人化邊界不得混入公共 HTML 快取;實驗分流必須明確進入鍵或在邊緣層完成隔離。
快取命中不能掩蓋來源資料過期。為片段記錄產生時間、失效時間與版本,命中舊資料時展示一致的更新時間策略。串流拼接後的整頁快取要謹慎,優先快取安全的片段。
第五步:保護可及性與版面穩定
fallback 與最終內容使用相同的語意標題、區域標籤與尺寸約束。替換內容不能讓鍵盤焦點跳到不可見節點;動態區域應有合適的狀態提示,避免頻繁朗讀整頁。
為圖片與媒體預留尺寸,使用穩定的骨架版面;監控 CLS。正文的關鍵內容應盡量在首個可視邊界內完成,不能把 LCP 元素放入不可控的長尾請求。
第六步:建立發布與觀測門禁
預發布測試覆蓋慢依賴、500、斷流、客戶端腳本失敗、快取污染與取消請求。線上按路由、邊界與依賴統計 TTFB、LCP、INP、邊界 p50/p95、逾時率、fallback 率與重試成功率。
灰度時先觀察 shell 與關鍵邊界,再逐步開放高風險個人化模組。若錯誤率或長尾耗時超過閾值,回退到上一版邊界編排或靜態 fallback,而不是繼續擴大流量。
高品質示範回答
我會先定義首屏預算與頁面可用性等級,再把正文 shell 與推薦、留言、個人化拆成獨立 Suspense 邊界。每個邊界有逾時、fallback、取消與追蹤 ID;失敗只影響該區域。公共片段按安全維度快取,個人化內容不進入公共快取。發布前用斷流與腳本失敗測試,線上同時看 LCP、INP、CLS、邊界 p95 與 fallback 率。
常見錯誤
- 把整頁包在一個邊界中 → 最慢依賴阻塞所有內容 → 按使用者可理解區域拆分。
- fallback 沒有固定尺寸 → 內容替換造成 CLS → 預留尺寸並保持語意結構。
- 將個人化 HTML 放入公共快取 → 使用者資料洩露 → 隔離私有片段並納入快取鍵。
- 伺服器逾時後客戶端無限重試 → 放大依賴壓力 → 設定預算、退避、上限與取消。
- 只測成功路徑 → 斷流或腳本失敗時整頁不可用 → 驗證錯誤、取消與無腳本降級。
追問及應對
追問一:邊界越多越好嗎?
不是。邊界應對應獨立的使用者區域與故障域;過細會增加 fallback 噪聲、監控成本與快取變體,過粗則擴大阻塞範圍。
追問二:如何保證錯誤不會中斷整條串流?
讓錯誤落在邊界的伺服器與客戶端恢復路徑中,保留已傳送 shell,並為每個邊界提供穩定 fallback。還要測試回應已部分傳送時的異常。
追問三:哪些指標最能證明方案有效?
同時看 TTFB、LCP、INP、CLS、邊界 p95、逾時率、fallback 率與重試成功率;單看平均回應時間會掩蓋長尾與局部故障。
追問四:如何避免快取洩露實驗或使用者資料?
把使用者、實驗、地區、語言與內容版本等安全維度明確納入鍵;無法證明安全的片段不進入公共快取,並用跨使用者回放測試驗證。