具代表性的面試主題

前端面試題:WebGPU 的 GPUDevice 遺失後如何安全復原?

前端困難
Offer.cc 編輯團隊發佈 更新

題幹

WebGPU 的 GPUDevice 遺失後如何安全復原?

題幹與適用場景

一個瀏覽器圖形應用在背景恢復、驅動程式更新或系統資源緊張後出現黑屏。請設計 WebGPU 裝置遺失處理:如何監聽 GPUDevice.lost,區分主動銷毀與瞬時遺失,重建裝置和所有 GPU 資源,並避免多個復原流程互相覆蓋。還要說明不支援 WebGPU、配接器永久不可用和渲染狀態恢復時的降級體驗。

面試官考察點

  • 是否理解 lost 是裝置生命週期 Promise,而不是普通渲染錯誤。
  • 能否區分 destroyed 與瀏覽器、驅動程式或資源管理造成的遺失。
  • 能否重建 adapter、device、pipeline、buffer、texture 和 bind group。
  • 能否設計 single-flight 復原、取消舊幀和冪等資源初始化。
  • 能否處理安全內容、Worker、相容性和可觀測性。

回答前需要釐清的問題

  • 應用是即時畫布、編輯器還是離線計算,允許多長復原時間?
  • 是否必須保留 CPU 端場景、使用者輸入和未提交編輯?
  • 目標瀏覽器、Worker、裝置功耗和顯存上限是什麼?
  • 復原失敗時應切換 WebGL、靜態預覽還是提示使用者重新載入?

30 秒回答框架

我會把 GPU 裝置視為可替換的工作階段:CPU 端場景與資源描述保持權威,GPU 物件只是快取。監聽 device.lost 後用 single-flight 狀態機暫停提交,讀取 GPUDeviceLostInfo.reason;主動 destroyed 直接結束,其他原因嘗試重新申請 adapter 和 device,再按描述重建資源並恢復渲染。連續失敗或 adapter 只回傳已遺失裝置時切換降級路徑,同時記錄原因、復原時間和資源重建失敗點。

分步驟深入解答

1. 區分裝置與應用狀態

把場景樹、材質參數、幾何資料和紋理來源保存在 CPU 端。device、queue、buffer、texture、pipeline 和 bind group 屬於可丟棄的 GPU 工作階段,不能把它們當作業務真相。

2. 監聽生命週期 Promise

GPUDevice.lost 在裝置存活期間保持 pending,裝置遺失時解析為 GPUDeviceLostInfo。初始化完成後只註冊一次監聽,讓回調進入統一復原狀態機。

3. 解釋遺失原因

主動呼叫 GPUDevice.destroy() 通常對應 reasondestroyed,不應無條件重啟。瀏覽器資源管理、驅動程式更新或暫時裝置故障可能可復原;adapter 被拔出或因省電停用時,後續裝置可能一建立就已遺失。

4. 使用 single-flight 復原門

復原入口回傳同一個 Promise,禁止每個渲染幀各自呼叫初始化。復原期間暫停提交、丟棄舊 command encoder,並用 generation 標記拒絕舊裝置的非同步回調,避免舊資源覆蓋新工作階段。

5. 按描述重建資源

保存 buffer usage、紋理尺寸和格式、取樣器、bind group layout、shader 原始碼和 pipeline 設定。新 device 建立後按相依順序重建:shader 與 layout、pipeline、buffer/texture、view、bind group,最後恢復 canvas context 和渲染迴圈。

6. 管理 CPU 資料與預算

大紋理和幾何資料可來自可重讀的 URL、IndexedDB 或壓縮快取。復原時按可見性和優先級分批上傳,設定顯存預算與取消訊號,避免裝置剛恢復就再次觸發資源壓力。

7. 處理並發與可見性

頁面隱藏、Worker 訊息和使用者重試都可能觸發復原請求。用狀態機約束 readylostrecoveringdegraded,只有目前 generation 能提交幀;頁面不可見時可延遲昂貴重建。

8. 設計降級與觀測

先檢查安全內容和 navigator.gpu,再申請 adapter/device。連續復原失敗、裝置永久遺失或瀏覽器不支援時切換 WebGL、靜態預覽或明確重新載入提示。記錄 reason、adapter 資訊、復原次數、耗時、重建失敗資源和降級比例,不把內部錯誤直接暴露給使用者。

設計取捨與邊界

重新申請 device 不會自動恢復舊的 buffers、textures 或 pipelines,它們必須從 CPU 端描述重建。復原策略不能假設所有遺失都是瞬時的,也不能在沒有退避的情況下無限重試。WebGPU 需要安全內容且仍是有限可用特性;Worker 可使用該 API,但瀏覽器矩陣和裝置驅動差異必須納入發布門檻。

落地計畫與證據

  1. 建立 CPU 資源清單和 GPU 資源工廠,所有物件建立都可重複執行。
  2. 為 device、adapter、canvas context 和渲染迴圈加入 generation 與 single-flight 復原狀態。
  3. 注入主動銷毀、背景恢復、驅動程式重置、顯存壓力和 adapter 已遺失裝置情境。
  4. 驗證資源重建順序、使用者編輯保留、幀暫停和降級 UI,並涵蓋 Worker。
  5. 以 MDN 的 lost Promise、GPUDeviceLostInfo、安全內容和有限支援說明作為文件與相容性依據。

常見誤區與追問

誤區一:只重新呼叫 requestDevice

新 device 不包含舊資源。必須從 CPU 描述重建 pipeline、buffer、texture、view 和 bind group。

誤區二:所有 reason 都自動重試

主動銷毀可能是應用正常關閉;adapter 永久不可用時重試只會製造迴圈。應按 reason 和退避策略分流。

誤區三:在每個動畫幀啟動復原

多個復原流程會競爭共享狀態。用 single-flight Promise 和 generation 門保證只有一個目前工作階段。

誤區四:把 GPU 物件當作業務狀態

裝置遺失會清空 GPU 工作階段。場景、使用者輸入和資源來源必須獨立於 device 保存。

誤區五:忽略不支援和降級路徑

WebGPU 仍非 Baseline,且只在安全內容可用。應提前檢查並提供 WebGL、靜態預覽或重新載入方案。

公開來源

同類題目