页面一跳转就要等浏览器撕掉重画?这件事今天被两个 API 彻底变了

MPA 最难受的一刻:用户点一个链接,整个页面像撕纸一样被浏览器清掉,然后下一屏再一片一片画出来。你以前只能忍,或者装一个动画库把整个路由层换掉。

这件事,2026 年被两个 Baseline API 从根上变了:一个管动画过渡,一个管路由拦截,加起来三行 CSS 替代几十行路由逻辑。

Cross-document View Transitions 让浏览器在两个页面之间自动快照、旧页淡出、新页淡入,不需要 JS,不需要构建步骤,Chrome 126+ 和 Safari 18.2+ 已经支持。写法就是一行 CSS:

@view-transition { navigation: auto; }

把这句话加到两个同源页面的样式表里,用户在这两个页面之间点链接,浏览器自动跑一个跨文档过渡动画。Safari 18.2 官方演示里,那个从列表页到详情页的 cross-fade 就是一行 CSS 跑出来的,没有任何 JS。

但这个 API 有一个性能代价要注意。Core Web Vitals 研究数据表明,跨文档 View Transitions 在移动端重复访问时会让 LCP 增加大约 70ms——不是因为动画本身慢,而是快照和合成这个过程在低端机上需要额外的主线程时间。桌面端影响很小,大约 5ms。

缓解方案有两个:

第一,Speculation Rules API 预渲染下一页。如果你的导航行为可预测(大多数内容站点都是),可以在当前页面加一条预渲染规则,让浏览器在用户 hover 到链接时就提前把下一页跑起来。这样当用户真正点击时,页面已经在了,LCP 那 70ms 代价完全被吃掉,transition 几乎零感知。

<script type="speculationrules">
{
  "prerender": [{
    "where": { "href_matches": "/articles/*" },
    "eagerness": "moderate"
  }]
}
</script>

第二,用媒体查询控制启用范围。过渡动画在桌面快速机上代价很低,但在低端 Android 上 70ms 是真实感受。可以用 prefers-reduced-motionmin-width 把动画限制在你确定体验更好的场景里:

@media (prefers-reduced-motion: no-preference) and (min-width: 768px) {
  @view-transition { navigation: auto; }
}

这两条规则加上之后,主流桌面用户得到完整的过渡动画体验,低端移动用户得到即时导航——没有任何信息损失。


Navigation API 解决的是 MPA 路由的另一半问题:History API 二十年的碎片化。三个独立 API(pushState/popstate/手动 link 拦截)拼出来的路由逻辑,换成一个统一的 navigate 事件:

navigation.addEventListener("navigate", (e) => {
  const url = new URL(e.destination.url);
  e.intercept({
    handler() {
      renderRoute(url.pathname);
    }
  });
});

一个事件替代了原来分散在 popstate、click handler 和 initial render 里的三坨逻辑。e.intercept() 还会自动帮你处理 URL 更新、历史栈、焦点管理、滚动恢复——这些以前全是自己要写的。

Navigation API 在 2026 年 1 月正式 Baseline,Chrome/Edge/Firefox 147/Safari 26.2 全部支持。但 Safari 目前缺少 precommitHandler——也就是 URL 改变之前的那段处理逻辑(比如在旧内容还在显示时先发请求拿数据)。Jake Archibald 在官方视频里专门指出了这个,期待 Safari 跟进。


两个 API 的关系

  • Navigation API 是路由层,负责「谁来处理这次导航」
  • Cross-document View Transitions 是展示层,负责「导航时怎么过渡」

在 MPA 里,Navigation API 触发同文档内的路由切换(如果你们用的是 History API 模式),Cross-document View Transitions 负责页面之间的跳转动画。如果你的站点页面之间是 <a> 链接跳转而不是 SPA 路由,只用第一个就够了——Safari 18.2 已经支持,不需要任何 JS。


下一步:今天在你的页面样式表里加一行 @view-transition { navigation: auto; },然后在 DevTools Network 面板里看一次移动端 3G 下的 LCP 差值。如果差值在 50ms 以内、用户机型偏新,这个改动零成本换体验,立刻值得上。如果 LCP 差值明显,加上 Speculation Rules 预渲染把代价吃掉。

两个 API 加起来三行 CSS,换掉的是一个路由库加一个动画库——这笔账值得算。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 14 阅读