題幹與適用場景
這是瀏覽器平台與發布工程結合的前端題。應用已有 WebGL 或 CPU 路徑,想在支援 WebGPU 的裝置上啟用更高效能渲染,同時覆蓋只能提供受限 API 子集的裝置。題目要求討論 compatibility mode 的能力偵測與限制差異,不能把「取得 adapter」誤當成「所有 shader、格式與效能都可用」。
GPUWeb 規範把 compatibility mode 定義為受限的 WebGPU 子集,目標是映射到較舊圖形 API;實作仍可能拒絕 adapter、限制可用 feature,或在執行中遺失 device。發布方案必須把可用性、正確性與效能分開量測。
面試官考察點
- 是否先建立能力矩陣,再選擇 adapter、feature 與 limits。
- 是否把 core、compatibility、WebGL 與 CPU 路徑定義成有序的產品降級,而不是一段布林判斷。
- 是否知道
GPUDevice.lost是非同步終止訊號,恢復需要重建資源與渲染狀態。 - 是否能設計真實裝置灰度、品質門檻、隱私友善的遙測與快速回滾。
- 是否能區分「渲染正確」「延遲達標」與「功耗可接受」三種結果。
回答前需要澄清的問題
- 目標是渲染、通用計算還是瀏覽器內推理?不同用途對 storage、紋理格式與精度要求不同。
- 低階裝置必須保留什麼體驗?答案決定 WebGL、CPU 或靜態結果的最低路徑。
- 是否允許首次載入做短暫 capability probe?若不允許,只能依賴歷史裝置輪廓並承擔誤判。
- 裝置遺失時能否重新初始化 canvas 與資源?如果不能,必須提前設計可恢復的 UI 狀態。
- 灰度按瀏覽器、GPU、驅動程式、地區還是使用者分組?分組決定如何發現特定驅動回歸。
30 秒回答框架
「我會先偵測 WebGPU、adapter、feature 與 limits,再把 core、compatibility、WebGL、CPU 或靜態結果作為明確能力階梯。初始化只建立符合該階梯的 shader、pipeline 與資源;每個關鍵路徑都有正確性測試與效能預算。監聽 device.lost,用單飛恢復流程重建 device、資源與 canvas 狀態,失敗則降級並記錄原因。灰度按瀏覽器、GPU、驅動程式與應用版本分層,監控初始化成功率、裝置遺失、渲染錯誤、p95 畫格耗時與電量代理指標,異常時關閉新路徑而不改變舊路徑。」
分步驟深入解答
第一步:把能力偵測寫成契約
先確認安全上下文與 navigator.gpu,再請求 adapter。adapter 返回後讀取可用 features 與 limits;不要只檢查 API 物件存在。將結果分類為 core、compatibility、WebGL 或 CPU,並把瀏覽器、作業系統、GPU vendor、驅動程式與應用版本作為匿名化遙測維度。
Compatibility mode 的價值是擴大可執行裝置範圍,代價是可用 feature、limits 與效能上限更保守。應用應把必要能力寫成清單:紋理格式、綁定配置、storage 大小、workgroup 上限與精度。缺少任一必要能力時,選擇下一階路徑,不要等到 shader 建立才失敗。
第二步:讓渲染資源隨能力檔位建構
每個檔位有自己的 shader 變體、pipeline 描述與資源預算。先建構最小三角形或小批量推理的 smoke test,確認 command submission 與結果校驗,再進入完整場景。不要假設 core 路徑建立的 bind group 或紋理格式在 compatibility 也被接受。
若資源建立失敗,記錄結構化錯誤並釋放該檔位物件。靜態後備圖、WebGL canvas 或 CPU 結果必須共享產品狀態模型,保證使用者仍能完成任務;後備路徑不能暗示有同等畫格率或精度。
第三步:處理裝置遺失與恢復競態
GPUDevice.lost 會在 device 生命週期結束時 resolve。監聽後進入 recovering 狀態:停止提交新 work,取消或標記舊畫格,重新請求 adapter/device,依能力檔位重建 shader、pipeline、buffer、texture 與 bind group,最後恢復渲染迴圈。用 generation token 或單飛 promise 防止兩個恢復流程交叉覆蓋新 device。
若 lost 原因表示資源壓力或驅動程式問題,重試次數與間隔必須有上限。連續失敗時切換 WebGL 或 CPU,讓 UI 說明功能已降級。既有 device-loss 題著重恢復實作;本題更關注 compatibility 能力矩陣與發布控制,兩者要分開回答。
第四步:設計灰度與回滾
先在內部裝置矩陣執行,再按瀏覽器版本、GPU vendor、驅動程式、作業系統與地區逐層擴大。灰度開關必須能在服務端或設定層快速關閉,但不能讓設定下發成為渲染正確性的單點依賴;用戶端始終保留安全預設值。
核心指標包括 adapter 請求失敗率、device 建立失敗率、首次可互動時間、p50/p95 畫格耗時或推理延遲、shader/pipeline 錯誤、裝置遺失率、恢復成功率、降級率與任務完成率。依硬體分層後才看得出某一驅動程式的回歸。遙測只保留粗粒度裝置標籤與版本,避免收集完整指紋。
第五步:驗證正確性、效能與功耗
正確性測試比較 WebGPU、compatibility、WebGL 與 CPU 的結果容差、紋理顏色、幾何邊界與推理輸出。效能測試固定場景、解析度與 batch,報告 p50/p95,不把單台旗艦裝置的平均值當作保證。背景或低電量場景還要測提交頻率、記憶體與裝置溫度代理訊號。
回歸門檻應依檔位設定:compatibility 只需滿足產品最低畫格率與結果誤差,不能把 core 預算硬套。若新路徑造成錯誤率、功耗或恢復時間越過門檻,關閉該檔位並保留 WebGL/CPU 結果,隨後用最小重現收集驅動程式資訊。
設計取捨與邊界
#### 只用 API 偵測 vs 裝置輪廓
即時偵測最準確,卻增加首次載入成本;裝置輪廓能快速決策,卻可能過期或形成指紋。用短偵測確認硬能力,輪廓只用於排序與灰度,不用來繞過實際 limits。
#### Compatibility mode vs WebGL
Compatibility mode 可以保留 WebGPU 的資源與命令模型,便於共享部分架構;WebGL 覆蓋面與成熟度可能更好,但 shader、同步與效能模型不同。依必要能力、正確性遷移成本與使用者任務選擇,不看 API 新舊。
#### 自動恢復 vs 立即降級
一次有界恢復適合短暫資源壓力;無限重試會造成卡頓與功耗放大。恢復失敗或連續遺失達到門檻後,立即切換後備路徑並記錄一次可診斷事件。
高品質示範回答
「我會把 WebGPU 發布拆成能力矩陣、資源建構、恢復狀態機與灰度控制。先確認安全上下文、請求 adapter,再讀取 feature 與 limits,把 core、compatibility、WebGL、CPU 排成能力階梯;每階只建立它支援的 shader 與資源。監聽 device.lost 後停止提交,用 generation token 保證只有一個恢復流程,重新建立 device 與全部 GPU 物件,失敗則降級。灰度按瀏覽器、GPU、驅動程式與版本分層,監控初始化、畫格耗時、錯誤、遺失、恢復與任務完成率,並保留遠端關閉開關。Compatibility mode 擴大覆蓋,不等於效能保證,所以正確性、延遲與功耗要分開驗收。」
常見錯誤
- 只檢查
navigator.gpu→ adapter 或 device 仍可能拒絕,feature 與 limits 也可能不足 → 建立能力矩陣並逐項驗證。 - 把 compatibility mode 當作低配 core → shader、格式與 limits 可能不相容 → 為檔位建立獨立資源清單與 smoke test。
- 裝置遺失後只重新呼叫渲染函式 → 舊資源屬於失效 device → 透過單飛恢復流程重建全部資源與狀態。
- 無限重試 device 建立 → 驅動程式故障會變成卡頓與功耗放大 → 設定次數、間隔與最終降級。
- 只看平均畫格率 → 少數 GPU 或長尾裝置可能徹底失敗 → 依瀏覽器、GPU、驅動程式分層看 p95 與任務完成率。
追問及應對
Compatibility mode 的 limits 比 core 小,如何決定能否執行?
把每個任務的硬需求寫成 feature、紋理格式、storage、workgroup 與精度清單,和實際 adapter limits 比較。滿足清單才進入該檔位;否則選擇 WebGL、CPU 或靜態結果,並在遙測中記錄缺失項。
device 遺失時使用者正在編輯內容,可以直接重新整理頁面嗎?
不能把重新整理當預設恢復。先把編輯狀態保存在應用層,暫停 GPU work,嘗試一次有界重建;重建失敗後切換後備渲染,保留編輯狀態並提示視覺效果已降級。只有狀態無法安全遷移時才要求重新載入,並給出恢復入口。
某個驅動程式的遺失率突然升高,如何回滾?
依 GPU、驅動程式、瀏覽器與應用版本確認分層異常,先關閉該組合的 compatibility 灰度,保留其他組合。檢查初始化、shader、資源壓力與 lost 原因,再用最小場景重現;修復後從內部裝置矩陣重新開始,不直接恢復全量。
如何證明 WebGL 後備沒有改變業務結果?
為同一輸入建立跨後端 golden 集,比較像素或推理輸出的允許誤差,並測試邊界、空輸入與高負載。業務完成率、結果正確率與延遲分別設門檻;視覺相似不代表推理數值或互動時序等價。