Speculation Rules 与预渲染:分析工具在预取页面上的常见误区
Chrome 的 Speculation Rules API 可以在用户点击之前就渲染页面。以下介绍它如何扭曲简单的分析数据——以及无 cookie、基于边缘的测量如何保持真实。
在点击之前就加载的页面
Speculation Rules API 现已在 Chromium 浏览器中广泛发布,它让站点可以声明浏览器应在导航之前预取或完整预渲染哪些 URL。当用户悬停或表现出访问意图时,目标页面可能已经在隐藏标签页中完成渲染,然后瞬间切换过来。其回报是激活时几乎为零的 Largest Contentful Paint。而对于测量而言,问题在于预渲染页面会在任何人决定访问它之前就运行你的脚本。
如果你的分析工具在页面加载时就触发一次 pageview,预渲染就会用从未真正发生的访问来虚增你的计数。更糟的是,它还会扭曲性能数据:在后台预渲染的页面所记录的耗时,与真实用户所体验到的情况毫无关联。
预渲染期间到底发生了什么
预渲染的文档会正常执行,但处于一种特殊的生命周期状态。document.prerendering 为 true,且页面尚未被激活到可见标签页中。prerenderingchange 事件会在——且仅在——用户真正导航到该页面时才触发。许多预渲染根本不会被激活;浏览器可能会将其丢弃。
这一点之所以重要,有两个原因:
- 计数问题。 在
DOMContentLoaded上简单调用sendBeacon会为一个可能永远不会被看到的文档报告一次 pageview。 - 性能归因问题。 Core Web Vitals 是相对于用户感知到的加载来定义的。web-vitals 库以及底层的 Paint Timing 和 Event Timing 规范会考虑预渲染的情况,从激活点而非原始导航起点开始测量。缺乏这种意识而收集的指标根本就是错误的。
正确的做法
Web 平台为你提供了清晰的信号。将任何测量推迟到页面真正对某个人可见时再进行:
if (document.prerendering) {
document.addEventListener('prerenderingchange', recordPageview, { once: true });
} else {
recordPageview();
}
对于计时,PerformanceNavigationTiming.activationStart 给出了导航起点与激活之间的偏移量。任何绘制或交互的时间戳都应相对于该值来测量,并将负值钳制为零。这正是 Google 的 web-vitals 库在内部所做的事情,因此如果你自行计算 LCP 或 INP,请照搬这一逻辑。
同样的原则也适用于 prefetch,它是 prerender 更轻量的近亲。Prefetch 只获取响应;它不执行脚本,因此很少直接污染分析数据。但它确实会消耗带宽,并可能扭曲服务端的请求日志——这提醒我们,原始日志计数与真实访问量之间的偏差比以往任何时候都更大。
为什么在没有 cookie 或客户端状态时这更容易处理
由投机驱动的预渲染对有状态的跟踪器来说是个麻烦。一个设置标识符、水合会话或写入存储的预渲染文档,都是在投机性地执行——为一次可能被丢弃的访问。清理这些数据、针对最终真实激活进行去重、以及协调跨页面身份,都会成为真正的错误来源和隐私风险。
Monoid 完全避开了这一整类问题。我们不在设备上存储任何东西——没有 cookie,没有 localStorage,没有指纹。没有需要创建又需要在之后撤销的投机性会话。测量是一个单一的、无状态的信号,我们只在页面变为真实时才发出它。由于收集在 Cloudflare 边缘运行,聚合处理的数据已经反映了真实、已激活的导航,而不是浏览器乐观的猜测。
这就是数据最小化在为你服务。当你不收集任何需要清理的数据时,投机性渲染就不会产生孤立的身份记录或重复的档案。它只是意味着你在计数之前等待 prerenderingchange。
预渲染安全分析的清单
- 让 pageview 的发出以
document.prerendering和prerenderingchange事件为条件。 - 相对于
activationStart计算 LCP、FCP 和 INP,或使用一个已经这样做的库。 - 将服务端请求日志视为真实访问的超集,而非其代理。
- 确认你的 Content-Security-Policy 允许从已激活的文档访问你的测量端点;在 Chrome DevTools 的预渲染面板中进行测试。
- 避免任何对设备存储的投机性写入——做到预渲染正确最干净的方式就是完全不保留任何客户端状态。
更宏观的意义
每一个新的性能原语——bfcache、软导航,以及现在的 speculation rules——都在悄然打破那个旧假设:一次页面加载等于一次人类访问。依赖 cookie 和有状态会话的分析工具不得不叠加越来越多的协调逻辑。而在真正可见的那一刻测量一个无状态事件的分析工具,只需尊重平台的生命周期事件即可。更快的页面与真实的数据并不矛盾;你只需在正确的时刻计数。
Comments
Loading comments…