题干与适用场景
新闻站点希望用 Speculation Rules API 加速文章详情跳转。请说明如何选择 prefetch 与 prerender、限制规则范围,并处理登录态副作用、数据新鲜度、浏览器降级、取消和监控。
Chrome 文档说明,prefetch 主要提前获取资源,prerender 会在不可见页面中加载并渲染;因此后者收益更高,也更容易提前触发脚本和副作用。题目考察性能工程、渐进增强和安全边界,不是背 API 字段。
面试官考察点
重点看候选人能否按导航命中概率和副作用风险选择策略;能否控制规则选择器、同源范围、缓存和隐私;能否在不支持 API 或预渲染被取消时保持正常导航;能否用真实用户指标证明收益而非只看实验室分数。
30 秒回答框架
“我先用高命中、只读、同源文章链接做保守 prefetch;只有确认页面无写入副作用、命中率高且资源预算允许时才 prerender。规则按模板和用户意图分层,登录、支付、个性化和有副作用的路由不预渲染。服务端用缓存和请求幂等保护,客户端检测 document.prerendering 并延迟分析上报。旧浏览器直接走普通导航,最后比较激活率、LCP、INP、带宽和取消率。”
分步骤深入解答
第一步:先划分导航风险
把文章详情、帮助页等只读页面列为候选;排除下单、登出、点赞写入、支付和强个性化页面。预渲染会执行页面生命周期代码,任何写请求都必须由用户真实激活触发。
第二步:选择 prefetch 或 prerender
低命中率或副作用不确定时只 prefetch。prerender 适用于高命中、同源、首屏稳定且可承受额外 CPU 与内存的页面。不要把整站所有链接设为 prerender;按模板或明确用户意图设置规则。
第三步:控制规则和资源预算
使用文档规则或服务器生成规则,仅匹配文章链接;限制并发候选数量和资源大小。为预取响应设置合适的缓存、Vary 和失效策略,避免把带用户私密数据的响应共享给错误用户。
第四步:隔离副作用与登录态
服务端写接口必须要求真实用户操作和 CSRF 防护,不能因为预渲染请求就改变状态。分析、广告和通知脚本在 document.prerendering 阶段延迟,激活后再发送一次且去重。个性化响应使用私有缓存或直接排除。
第五步:设计兼容与取消路径
不支持 Speculation Rules 的浏览器直接使用普通链接。预渲染可能因内存、网络或规则限制被取消,页面必须仍可正常加载。路由切换前不要依赖预渲染一定完成,也不要为了追求瞬时导航阻塞点击反馈。
第六步:处理数据新鲜度
文章内容变更频繁时缩短缓存并在激活时校验版本;对带 ETag 的资源使用条件请求。若预渲染页面已过期,激活后应静默刷新可变区域,不闪回旧内容,也不重复发送用户操作。
第七步:观测真实收益
分组比较启用与未启用用户的激活率、导航等待、LCP、INP、CLS、带宽、CPU、内存和取消率。按浏览器、网络、设备和登录状态分层;如果首屏更快但流量或错误率上升,应降低规则范围或回退到 prefetch。
设计取舍与边界
命中率与资源成本
prerender 命中率低时浪费 CPU、内存和带宽;prefetch 成本较低但收益有限。以真实激活率和资源预算设门槛,不能只凭主观“感觉会点击”。
新鲜度与瞬时导航
长缓存提高命中率却增加陈旧风险。对静态内容可使用版本化 URL;对动态内容在激活时校验,并将刷新限制在可变区域。
兼容性与维护成本
规则应是渐进增强层,普通链接始终可用。避免把业务状态机绑定在预渲染生命周期,减少跨浏览器差异带来的维护负担。
失败演练与演进计划
预渲染提前触发写请求
在测试环境记录所有预渲染请求,验证点赞、统计和通知接口没有副作用。发现写请求后立即移出规则,并把写操作改为真实激活后执行。
低命中率导致资源浪费
按设备和网络关闭低端环境的 prerender,比较带宽与 INP;逐步从 prefetch 小流量灰度到 prerender。
激活后内容过期
构造发布更新发生在预渲染与点击之间的场景,验证 ETag 校验和局部刷新,确保用户看到最新标题和正文。
常见误区与追问
误区一:所有链接都 prerender
追问:命中率、并发上限和内存预算是多少?候选人应给出规则筛选与关闭条件。
误区二:预渲染等同于缓存
追问:页面执行了哪些脚本?如何延迟分析和保护登录态?
误区三:只看 Lighthouse 分数
追问:真实用户的激活率、取消率和带宽变化如何分层验证?
误区四:没有普通导航回退
追问:浏览器不支持或预渲染被取消时,点击链路是否仍然可用?
误区五:忽略数据新鲜度
追问:文章在预渲染后更新,激活时怎样避免显示旧内容?
延伸追问与参考答案
为什么不直接对所有页面 prerender?
因为预渲染会消耗额外资源并可能执行脚本。应只选择高命中、只读、同源且有预算的页面。
如何避免分析事件重复?
在预渲染阶段检测 document.prerendering,延迟事件到激活,并用页面导航 ID 去重。
如何证明优化有效?
使用真实用户分流,比较激活导航的 LCP、INP、等待时间、带宽和取消率,并按设备和网络分层。