1. 題目
一個全球存取的單頁應用需要收集真實使用者效能資料,用來比較不同裝置、網路與版本的體驗。你需要採集 LCP、資源載入與長任務,同時限制每個頁面工作階段的上報量。請設計基於 PerformanceObserver 的採集器,並說明它如何處理頁面載入前已產生的項目、緩衝區遺失、跨網域資源與 SPA 路由切換。
2. 約束與澄清
- 先定義每個指標的時間範圍:初始文件、軟導覽,還是一次完整工作階段。
- 設定取樣率、每類項目上限、批次上報大小與失敗重試策略,避免採集器影響頁面。
- 區分瀏覽器支援差異與資料缺失;缺失值必須帶原因,不應預設為零。
- 明確資源 URL、使用者識別與查詢維度的隱私邊界,避免直接上報完整 URL 或敏感參數。
3. 核心概念
PerformanceObserver 透過觀察指定的 entry type 接收效能項目;buffered: true 可補取觀察器建立前已記錄的項目。資源、長任務、繪製與 LCP 等類型各有緩衝區限制,回呼還可以收到 droppedEntriesCount,用來發現緩衝區已遺失項目。LCP 是載入期間最大的圖片或文字區塊繪製時間,使用者互動後不應繼續把後續內容當成初始 LCP。跨網域資源若沒有合適的 Timing-Allow-Origin 回應標頭,計時資訊可能受到限制或缺失。
4. 參考實作
startCollector():
session = createSessionId()
observe("largest-contentful-paint", {buffered: true})
observe("resource", {buffered: true})
observe("longtask", {buffered: true})
observe(type, options):
if type not in PerformanceObserver.supportedEntryTypes:
markUnsupported(type)
return
observer = new PerformanceObserver((list, _, dropped) =>
appendSanitized(list.getEntries())
if dropped > 0: markDropped(type, dropped)
flushWhenBatchIsReady()
)
observer.observe({type, ...options})
onSoftNavigation(route):
closePreviousView(route)
resetViewScopedMetrics()初始化時為每類項目註冊獨立觀察器,優先使用 buffered 補取早期記錄;回呼只保留需要的欄位、裁剪 URL 參數並按批次傳送。每個視圖保存觀察器建立時間、路由與版本,軟導覽時結束舊視圖並重置視圖級指標;工作階段級資源或錯誤計數則使用明確的去重鍵繼續累計。
5. 資料品質與成本取捨
取樣率越高,分位數越穩定,但網路與儲存成本也越高。可以對 LCP、長任務保留較高樣本,對資源項目採用頭部取樣或只保留慢資源。單個 resource 緩衝區預設最多保存 250 條,採集器應在頁面生命週期內及時消費並記錄遺失數量,而不是無限提高上報頻率。客戶端批量傳送失敗時只做有限重試,並在下次頁面存取時丟棄過期批次,避免本地佇列拖慢啟動。
6. 驗證與觀測
- 在觀察器建立前製造項目,驗證
buffered能補取;在大量資源頁面驗證droppedEntriesCount告警。 - 用跨網域資源分別測試有、無
Timing-Allow-Origin時的欄位差異,並確認缺失原因可區分。 - 對初始載入、軟導覽、背景恢復與頁面隱藏分別重播,檢查 LCP 與資源項目不會跨視圖重複歸因。
- 監控採集器自身的 CPU、記憶體、上報位元組數、批次失敗率、項目遺失率與支援率。
7. 常見誤區
- 只在
load事件後建立觀察器,導致早期 LCP 或資源項目永遠缺失。 - 看到
droppedEntriesCount後靜默丟棄,卻繼續把不完整樣本當成完整分布。 - 把跨網域資源的受限計時當作真實的零延遲,污染效能分位數。
- SPA 每次路由都新建觀察器卻不關閉舊觀察器,造成重複上報與記憶體洩漏。
8. 面試評分點
能正確使用觀察器生命週期
應說明 buffered、supportedEntryTypes、觀察器關閉與軟導覽邊界,避免早期遺失與重複統計。
能處理緩衝區與跨網域限制
應監控 droppedEntriesCount,了解資源緩衝區上限,並用 Timing-Allow-Origin 解釋跨網域欄位缺失。
能設計可控的取樣與上報
應按指標價值分配取樣率、項目上限與批次策略,說明失敗重試不會反過來拖慢頁面。
能驗證資料可信度
應覆蓋早期項目、海量資源、跨網域、軟導覽與背景恢復場景,同時觀測採集器自身開銷與遺失率。