前端面試:如何設計兼顧隱私與快取的響應式圖片 Client Hints 方案?
題幹與適用場景
一個內容網站要在手機、平板與桌面提供不同寬度及 DPR 的圖片。產品希望降低首屏流量,CDN 卻擔心按每個 Width、DPR 建快取造成碎片;法務要求只收集必要裝置資訊。請設計方案,並說明不支援 Client Hints 時如何運作、如何避免 CLS 與重複下載、如何驗證收益。
適合考察瀏覽器資源選擇、HTTP 快取、效能、無障礙與漸進增強。題設寬度、DPR、流量都是待測變數,不應臆測固定收益。
面試官在考察什麼
- 能否用
srcset/sizes描述真實呈現槽位,讓瀏覽器在客戶端選候選圖。 - 能否把
Accept-CH、後續請求、Vary與 CDN 快取鍵串成完整資料流。 - 能否識別高基數 Client Hints 的隱私、指紋與快取爆炸風險。
- 能否設計無 JavaScript 依賴的回退、尺寸占位、
alt與量測閉環。
先釐清哪些問題
- 圖片是內容圖、裝飾圖還是需要藝術裁切的 Hero?用途會決定
alt與 picture 元素策略。 - 圖片槽位在各斷點的 CSS 寬度與比例是多少?
sizes必須描述槽位,不能只寫視口寬度。 - CDN 是否支援按規範化寬度、格式與品質參數建鍵?允許多少候選寬度?
- 目標瀏覽器對 Client Hints、現代圖片格式與響應式預載的支援範圍是什麼?
- 首屏指標、快取命中率、圖片位元組數與錯誤率的基線如何採集?
30 秒回答框架
先用 HTML 原生響應式圖片處理大多數請求,再把 Client Hints 作為伺服器/CDN 的漸進增強。瀏覽器用 srcset 與 sizes 選候選圖;伺服器若依提示改變回應,就宣告 Accept-CH,並讓快取策略反映真正影響回應的欄位。只允許白名單寬度與 DPR 桶,保留安全預設、尺寸占位與無提示回退。最後以 LCP、CLS、圖片位元組、命中率與錯誤率做對照實驗,檢查高熵提示是否真的必要。
分步作答
1. 先定義候選集與槽位
為每張圖產生有限寬度集合,例如 320、640、960、1280(示例值,不代表通用標準),並保留原始比例。sizes 按版面斷點表達預計顯示寬度;瀏覽器也會結合 DPR、網路與自身策略選候選。src 作為必要回退。
<img
src="/img/card-640.jpg"
srcset="/img/card-320.jpg 320w, /img/card-640.jpg 640w, /img/card-960.jpg 960w, /img/card-1280.jpg 1280w"
sizes="(min-width: 66rem) 33vw, (min-width: 44rem) 50vw, 100vw"
width="640"
height="400"
alt="文章封面"
loading="lazy"
decoding="async"
>2. 用 picture 處理格式與藝術方向
需要 WebP/AVIF 等格式或手機端不同裁切時使用 picture 元素,最後仍放一個帶 src 的 img 元素回退。格式選擇與寬度選擇分層,避免用固定預載誤導瀏覽器下載錯誤資源。
3. 設計 Client Hints 的最小閉環
回應可透過 Accept-CH 請求伺服器真正使用的提示,例如 DPR 或 Width;瀏覽器是否傳送、何時傳送受自身設定、權限策略與支援情況影響。伺服器收到提示後必須忽略不認識的欄位,只把確實改變回應的欄位納入快取變化說明。
Accept-CH: DPR, Width
Vary: Accept, DPR, WidthVary 是語意宣告,不代表可以無限擴展快取。先把 Width 映射到有限桶,對 DPR 規範化,或把規範化結果納入 CDN 鍵;不要把任意原始參數直接拼進上游 URL。
4. 處理隱私、權限與安全輸入
Client Hints 是請求中繼資料,不是身分憑證。優先使用低熵且確實有用的提示,避免請求裝置型號等高熵欄位做個體畫像。寬度、品質、格式參數必須做範圍校驗和白名單映射,圖片轉換服務還要阻止 SSRF、開放重新導向與超大尺寸消耗。
5. 保留漸進增強與無障礙
沒有 Client Hints、提示未獲允許或 CDN 未命中時,仍由 srcset/sizes 與伺服器預設寬度完成載入。提供 width、height 或等價比例盒降低 CLS;首屏 LCP 圖謹慎使用 loading="eager" 或 fetchpriority="high",折疊下方圖片才延遲載入;內容圖寫有意義的 alt。
6. 建立可回滾的量測
按相同內容與流量切分對照組,記錄 LCP、INP、CLS、圖片傳輸位元組、解碼耗時、命中率、錯誤率、實際顯示寬度與裝置類別。若命中率下降或重複下載增加,先減少提示維度、擴大寬度桶或撤回 Client Hints,不要繼續增加快取變體。
高品質示範答案
我會把瀏覽器原生選擇放在第一層:給圖片有限的 srcset 候選和準確的 sizes,並設定尺寸屬性與可存取的 alt。需要格式或藝術裁切時使用 picture 元素,img 元素仍提供可靠回退。伺服器可透過 Accept-CH 請求實際用於變體選擇的提示,但我會把它視為可缺省輸入:首個請求、未獲權限或不支援時仍回傳安全預設圖。
若回應會因提示改變,我會讓 CDN 的鍵只包含規範化寬度、DPR 桶、格式與品質白名單;Vary 只宣告真正影響回應的欄位。因為原始 Width 和網路提示可能有高基數,不能直接為每個值建快取。裝置型號等高熵資訊沒有業務必要就不請求,也不把提示當認證條件。最後用 LCP/CLS、位元組、命中率與錯誤率做同內容 A/B,確認沒有重複下載後再逐步擴大覆蓋。
常見失分點
- 把
sizes永遠寫成100vw,忽略多欄版面,導致候選圖過大。 - 只講
Accept-CH,不講後續請求、權限、Vary與快取鍵。 - 對每個原始寬度、DPR、網路值建立 CDN 變體,造成快取碎片。
- 依賴客戶端 JavaScript 先量測再請求,犧牲首屏與離線回退。
- 用固定 preload link 覆蓋響應式選擇,觸發錯誤或重複下載。
- 忽略
alt、尺寸占位、參數白名單與高熵提示的隱私風險。
追問與參考回答
Vary 是不是越多越正確?
不是。它應準確反映會改變可快取回應的請求欄位;高基數欄位會增加變體並降低命中率。可以先做規範化鍵,或改用有限伺服器預設策略。
為什麼已經有 srcset 還要 Client Hints?
srcset/sizes 讓瀏覽器掌握槽位並自主選擇,通常是首選。Client Hints 只在伺服器/CDN 必須依裝置或網路中繼資料生成回應時補充,且不能取代回退。
第一個 HTML 請求一定帶 Width 嗎?
不應如此假設。Accept-CH 協商影響後續請求,提示傳送還受瀏覽器支援和權限策略影響,因此首個請求必須可獨立工作。
如何判斷快取鍵桶是否太細?
觀察命中率、變體數量、邊緣儲存占用與每桶請求量;合併相鄰寬度後比較位元組與 LCP,若收益小於快取成本就收斂桶數。
什麼時候不應使用高熵提示?
當業務只需粗粒度寬度、格式或省流偏好時。裝置型號等欄位會增加指紋面和快取維度,不能因為「可能有用」就預設開啟。
如何測試預載不會重複下載?
在支援響應式預載的瀏覽器和回退瀏覽器分別擷取網路記錄,確認 preload 與最終 img 元素選擇同一 URL;不支援時讓 HTML 的 srcset 成為唯一可靠路徑。