目录
背景
最近公司在做一个基于 SDUI 架构(参加我的另一篇文章:初识 SDUI(Server-Driven UI,服务端驱动 UI))重写客户端(包括 web 端)的项目,我也参与了其中重写 web 端的部分。
项目选用的 web 框架是 Next.js,之前我曾粗浅了解过,这次终于有幸能用它来开发了!
疑点重重:Next.js 究竟是如何实现页面导航的?
服务端渲染,客户端导航
众所周知,Next.js 最大的特点(或者说卖点)是服务端渲染。服务端渲染的主要好处包括 SEO 效果好、TTFP(Time To First Page)时间短,缺点主要是服务端负荷会更大。
那么既然是服务端渲染,在我粗浅的理解中,页面跳转时就应该是从服务端拿到新页面,彻底刷新页面咯 ?就像 SPA 出现之前的传统网站一样。可是这样的用户体验难道不会很差吗?
后来发现,当然不是这样的!Next.js 采用了和 SPA 相同的客户端导航(Client Navigation)机制,也就是说,跳转到新页面时,只有变化的部分会刷新,不变的部分并不会做没有必要的刷新。
但这就引起了我一个很大的疑问:
疑点 1:客户端导航岂不会影响 SEO?
客户端导航是基于 JS 的。如果 Next.js 也是基于客户端导航的,那么服务端渲染最大的优势 SEO 不就化为泡影了!毕竟像 React、Vue 这样的 SPA 应用,不就是因为需要 JS 才能加载页面,导致搜索引擎爬虫(通常不运行 JS)无法爬取吗?
疑点2:JS 禁用也能跳转?
于是,怀着这样的疑问,我把 chrome 的 JS 禁用了,点了一个链接尝试跳转到新页面。
令我大惊失色的是,页面跳转居然成功了!!说好的客户端导航呢??你这明明不需要 JS 也能跳转页面啊!
原理:客户端导航和传统跳转相结合
后来我冷静下来,分析了一下终于明白是怎么回事了:
- Next.js 中,站内的页面导航的的确确是基于 JS 的客户端导航。但和一般的客户端导航不同的是,每个“链接”下面都有一个真真正正的
<a>
元素!正常用户点击这个链接,JS 会通过客户端导航的方式渲染新页面,同时阻止<a>
跳转生效; - 在禁用 JS 的情况下,点击链接时基于 JS 的客户端导航不会生效,但
<a>
的传统跳转仍然会生效。这样一来,整个页面都会刷新,加载在服务端渲染好的新页面。
一箭双雕
我简直想不到比“一箭双雕”更适合形容 Next.js 这种导航机制的词了!
- 普通用户可以运行 JS,在这种情况下,基于 JS 的客户端导航显然有完胜传统导航的用户体验!
- 搜索引擎爬虫不运行 JS,在这种情况下,仍然可以根据页面内的
<a>
元素进行跳转,爬取站内页面,SEO 效果满分,完胜 SPA!
总结为下表:
传统网站 | SPA | Next.js |
---|---|---|
用户体验差 | 用户体验好 | 和 SPA 一样好! |
SEO 效果好 | SEO 效果差 | 和传统网站一样好! |
这个设计,简直绝了!
延伸阅读
可以参考我的另一篇文章 Next.js 实现原理系列:Link 与 Router (1),了解更多实现细节。