Soft Navigations:用浏览器的方式衡量 SPA 性能
Chrome 的软导航启发式终于让 Core Web Vitals 能够附着到客户端路由切换上。本文讲清这套 API 如何工作,以及如何在不进行监控的前提下衡量它。
十年来,Core Web Vitals 只描述访问者加载的第一个页面。在单页应用中,此后的每一次路由切换对指标都是不可见的。Chrome 的**软导航(soft navigations)**实验弥补了这个缺口,也改变了注重隐私的分析工具应当如何衡量真实用户性能。
软导航修复的盲区
传统的**硬导航(hard navigation)**会卸载当前文档并加载一个新文档。浏览器重置其性能时间线,触发一次新的 LCP,并从零开始统计 CLS 和 INP。CrUX 等现场工具会把一切都归到那一个 URL 上。
SPA 不是这样工作的。在首次加载之后,React Router、Next.js 的 App Router 或 SvelteKit 会通过 History API 就地替换内容。没有文档被卸载,因此不会开始新的性能时间线。用户可能点击浏览十个"页面",而每一项 Core Web Vital 仍然钉在入口 URL 上。
审计过 SPA 的人都熟悉这个结果:着陆路由看起来很快,而应用深处那些缓慢的交互从不出现在数据里。
Chrome 如何检测一次软导航
Chrome 的启发式要求在记录一次软导航之前,按顺序发生三件事:
- 导航由用户交互发起——一次点击或一次按键。
- URL 通过 History API 或 Navigation API 被修改。
- 交互之后跟随一次 DOM 修改,改动一个已经存在的 DOM 元素。
这个序列是刻意严格的。用于分析的后台 pushState、自动轮播的轮播图,或没有交互的 URL 变更都不符合条件。这种精确性很重要:它意味着一次软导航对应的是人真正做过的事,而不是附带的脚本活动。
API 表面
软导航通过标准的 PerformanceObserver 使用一个专用的 entry 类型暴露出来。你按 observer 逐个启用:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(entry.name, entry.startTime);
}
}).observe({ type: "soft-navigation", buffered: true });
更重要的是,其他性能 entry 获得了 navigationId。在软导航之后发出的 LCP、layout-shift 和 event-timing entry 都会带上这个新 ID,于是你可以把每一项 Core Web Vital 重新归因到用户实际所在的路由:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// entry.navigationId 把这次 LCP 与某次具体的软导航关联起来
send({ metric: "LCP", value: entry.startTime, navId: entry.navigationId });
}
}).observe({ type: "largest-contentful-paint", buffered: true });
如今这一切藏在 chrome://flags/#soft-navigation-heuristics 和一个 origin trial 后面,在 CrUX 中的暴露有限。它在稳定版 Chrome 中还不是默认行为,因此请把现场数据当作方向性参考,而非权威结论。web-vitals 库通过它的 reportSoftNavs 选项暴露同样的数据,这是无需手写 observer 即可接入的实用方式。
为什么这属于注重隐私的分析
软导航数据是纯粹的计时数据。它不含标识符、不含 cookie,也不含任何能在页面会话之后存活的东西——一个时长、一个粗略的元素类型、一条路由路径。这正是无 cookie 工具可以采集、而无需触碰同意机制的那类信号。
追踪器已经挂钩了 history.pushState 来统计 SPA 的路由切换。软导航对同一个钩子做了细化:不再只问路由变了吗,而是可以问这是一次由交互驱动的导航吗,它表现如何。性能 entry 与现有的 pageview 信标一起发往 /collect,在不给小于 2 KB 的脚本增加负担、也不破坏每日哈希身份模型的前提下,加入了现场测量。
要避免的陷阱是把软导航当成采集更多数据的理由。一些 RUM 厂商会用这套新归因把单个用户的导航旅程在一次会话中串联起来——这正是无 cookie 分析存在的意义所要拒绝的监控模式。这项指标之所以有价值,恰恰在于它可以保持聚合:每条路由的 INP 中位数、每条路由的 LCP 分布,没有任何回溯到某个人的路径。
软导航第一次让你应用中最深、最慢的部分变得可衡量。采集计时,丢弃其余一切,你就能得到性能图景,而不带画像。