自动静态优化

如果页面没有阻塞性数据需求,Next.js 会自动判定该页面是静态的(可被预渲染)。这一判定基于页面中是否包含 getServerSidePropsgetInitialProps 方法。

此功能使 Next.js 能够生成包含 服务端渲染页面和静态生成页面 的混合应用。

静态生成的页面仍然具有响应性:Next.js 会在客户端对应用进行水合 (hydrate),使其具备完整的交互能力。

该功能的主要优势在于,优化后的页面无需服务器端计算,可以直接从多个 CDN 节点即时传输给终端用户。从而为用户带来 极速 的加载体验。

工作原理

如果页面中包含 getServerSidePropsgetInitialProps,Next.js 会切换为按需渲染(即 服务端渲染 (SSR))。

如果上述条件不满足,Next.js 将通过预渲染页面为静态 HTML 的方式,自动进行静态优化

在预渲染阶段,路由器的 query 对象将为空,因为此阶段我们无法提供查询信息。水合完成后,Next.js 会触发应用更新,将路由参数填入 query 对象。

以下情况会导致水合后更新查询参数并触发重新渲染:

要判断查询参数是否已完全更新并可供使用,可以利用 next/router 中的 isReady 字段。

须知:对于使用 getStaticProps 的页面,通过 动态路由 (dynamic routes) 添加的参数始终会出现在 query 对象中。

执行 next build 时,会对静态优化过的页面生成 .html 文件。例如,pages/about.js 页面的构建结果会是:

Terminal
.next/server/pages/about.html

如果在该页面中添加 getServerSideProps,则会生成 JavaScript 文件:

Terminal
.next/server/pages/about.js

注意事项

  • 如果在 自定义 App 中使用 getInitialProps,则未使用 静态生成 (Static Generation) 的页面将禁用此优化
  • 如果在 自定义 Document 中使用 getInitialProps,请确保在假设页面是服务端渲染前检查 ctx.req 是否已定义。对于预渲染的页面,ctx.req 会是 undefined
  • 在路由器的 isReady 字段为 true 之前,避免在渲染树中使用 next/routerasPath 值。静态优化页面仅在客户端知道 asPath,服务端并不知晓,因此将其作为 prop 使用可能导致不匹配错误。active-class-name 示例 演示了将 asPath 作为 prop 使用的一种方式

On this page