自动静态优化

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

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

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

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

工作原理

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

如果上述情况不存在,Next.js 将通过预渲染页面为静态 HTML 的方式自动静态优化您的页面。

在预渲染阶段,路由器的 query 对象会是空的,因为在此阶段我们无法提供 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