目录
背景
这是 Next.js 实现原理系列的第 3 篇,承接之前对 Link 和 Router 的讨论,来看看页面渲染的原理。
本篇主要回答下面这个问题:
- 在 Next.js 中,切换 Page 时,为什么页面上不变的部分也会被重新渲染?
搞懂了这个问题,也就能大致明白 Next.js 页面渲染的原理了。
注:本系列文章基于 Next.js v12.0.4 版本。
切换 Page 时,为什么页面上不变的部分也会被重新渲染?
你也许注意过,在 Next.js 中切换 Page 时,页面上即使是不变的部分(例如 header)也会被重新渲染,这一点和常规的 React SPA 完全不同。如下图所示:
上面这个例子使用的是 Next.js 的官方网站 https://nextjs.org,它本身就是使用 Next.js 搭建的。可以看到,如果你把 header 的背景色修改为黄色,再切换到另一个页面,header 的黄色就不见了,说明它被重新渲染过。
这不能不说有些令人意外。虽然看不到源码,但这两个页面显然使用的应该是同一个 header 组件,没有任何理由应该重新渲染一遍。为了确认这一点,我自己新建了一个 project 试了一下,发现如果有 pages/a.js
和 pages/b.js
这两个 page,并且它们都引用了同一个组件 C,那么在 a 和 b 之间通过链接切换时,C 的确会重新渲染。
你可能会说,是因为 Next.js 在服务端渲染吧!并非如此,因为当你第一次访问这个网站的时候,拿到的 HTML 确实是在服务端渲染好的,但在进行后续的站内页面切换时,Next.js 采用的也是客户端渲染,换句话说和常规的 React SPA 应用没有区别(关于这一点可以参考我的另一篇文章:一箭双雕:浅谈 Next.js 页面导航(page navigation)原理)。如果你用 create-react-app
创建一个常规的 React SPA 应用,就绝对不会出现这样的事情。
当然了,Next.js 中并不是没有避免相同组件重复渲染的方法!只不过上面的例子没有使用而已。如果你希望 header 不要重复渲染,那么可以新建一个 pages/_app.js
文件:
// pages/_app.js
import React from 'react';
import Layout from '../components/Layout';
function MyApp({
Component, pageProps }) {
return (