代表性面试主题

前端面试:如何设计兼顾隐私与缓存的响应式图片 Client Hints 方案?

前端困难
Offer.cc 编辑团队发布 更新

题干

内容站点需要按设备宽度与 DPR 提供图片,但 CDN 担心缓存碎片、法务担心设备指纹。请设计完整方案并说明回退与验证。

题干与适用场景

一个内容站点要在手机、平板和桌面端提供不同宽度与 DPR 的图片。产品希望降低首屏流量,CDN 又担心按每个 WidthDPR 建缓存导致缓存碎片;法务要求只收集必要的设备信息。请设计方案,并说明不支持 Client Hints 时如何工作、如何避免 CLS 与重复下载、如何验证收益。

适合考察浏览器资源选择、HTTP 缓存、性能、可访问性和渐进增强。题设中的宽度、DPR、流量均为待测变量,不应凭空承诺固定百分比收益。

面试官在考察什么

  • 能否用 srcset/sizes 描述真实渲染槽位,让浏览器在客户端选候选图。
  • 能否把 Accept-CH、后续请求、Vary 和 CDN 缓存键连成完整数据流。
  • 能否识别高基数 Client Hints 的隐私、指纹和缓存爆炸风险。
  • 能否设计无 JavaScript 依赖的回退、尺寸占位、alt 与测量闭环。

先澄清哪些问题

  1. 图片是内容图、装饰图还是需要艺术裁切的 Hero?不同用途决定 alt 与 picture 元素策略。
  2. 图片槽位在各断点的 CSS 宽度和比例是多少?sizes 必须描述槽位,不能只写视口宽度。
  3. CDN 是否支持按规范化宽度、格式和质量参数建键?允许多少候选宽度?
  4. 目标浏览器对 Client Hints、现代图片格式和响应式预加载的支持范围是什么?
  5. 首屏指标、缓存命中率、图片字节数和错误率的基线如何采集?

30 秒回答框架

先用 HTML 原生响应式图片解决大多数请求,再把 Client Hints 作为服务器/CDN 的渐进增强。浏览器用 srcsetsizes 选择候选图;服务器若根据提示改变响应,就声明 Accept-CH,并让缓存策略体现真正影响响应的字段。只允许白名单宽度与 DPR 桶,保留安全默认值、尺寸占位和无提示回退。最后以 LCP、CLS、图片字节、命中率和错误率做对照实验,并检查高熵提示是否真的必要。

分步作答

1. 先定义候选集与槽位

为每张图生成有限宽度集合,例如 320、640、960、1280(示例值,不代表通用标准),并保留原始比例。sizes 按布局断点表达预计显示宽度;浏览器还会结合 DPR、网络和自身策略选择候选。src 作为必要回退。

html
<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 元素回退。格式选择与宽度选择分层,避免用一个固定 preload 误导浏览器下载错误资源。

3. 设计 Client Hints 的最小闭环

响应可通过 Accept-CH 请求服务器真正使用的提示,例如 DPRWidth;浏览器是否发送、何时发送受自身设置、权限策略和支持情况影响。服务器收到提示后必须忽略不认识的字段,并只将确实改变响应的字段纳入缓存变化说明。

http
Accept-CH: DPR, Width
Vary: Accept, DPR, Width

Vary 只是语义声明,不等于可无限扩展缓存。对 Width 先映射到有限桶,对 DPR 进行规范化,或把规范化结果纳入 CDN 键;不把原始任意查询参数直接拼进上游 URL。

4. 处理隐私、权限与安全输入

Client Hints 是请求元数据,不是身份凭证。优先使用低熵且确实有用的提示,避免请求设备型号等高熵字段来做个体画像。宽度、质量、格式参数必须做范围校验和白名单映射,图片转换服务还要阻止 SSRF、开放重定向和超大尺寸消耗。

5. 保留渐进增强与可访问性

没有 Client Hints、提示未获允许或 CDN 未命中时,仍由 srcset/sizes 和服务器默认宽度完成加载。为图片提供 widthheight 或等价的比例盒,降低 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 成为唯一可靠路径。

公开来源

同类题目