自动静态优化
如果页面没有阻塞性数据需求,Next.js 会自动判定该页面是静态的(可被预渲染)。这一判定基于页面中是否包含 getServerSideProps
和 getInitialProps
方法。
此功能使 Next.js 能够生成包含 服务端渲染页面和静态生成页面 的混合应用。
静态生成的页面仍然具有响应性:Next.js 会在客户端对应用进行水合 (hydrate),使其具备完整的交互能力。
该功能的主要优势在于,优化后的页面无需服务器端计算,可以直接从多个 CDN 节点即时传输给终端用户。从而为用户带来 极速 的加载体验。
工作原理
如果页面中包含 getServerSideProps
或 getInitialProps
,Next.js 会切换为按需渲染(即 服务端渲染 (SSR))。
如果上述条件不满足,Next.js 将通过预渲染页面为静态 HTML 的方式,自动进行静态优化。
在预渲染阶段,路由器的 query
对象将为空,因为此阶段我们无法提供查询信息。水合完成后,Next.js 会触发应用更新,将路由参数填入 query
对象。
以下情况会导致水合后更新查询参数并触发重新渲染:
- 页面使用 动态路由 (dynamic-route)
- URL 中包含查询参数
- 在
next.config.js
中配置了 重写规则 (Rewrites),因为这些规则可能需要解析参数并填入query
对象
要判断查询参数是否已完全更新并可供使用,可以利用 next/router
中的 isReady
字段。
须知:对于使用
getStaticProps
的页面,通过 动态路由 (dynamic routes) 添加的参数始终会出现在query
对象中。
执行 next build
时,会对静态优化过的页面生成 .html
文件。例如,pages/about.js
页面的构建结果会是:
如果在该页面中添加 getServerSideProps
,则会生成 JavaScript 文件:
注意事项
- 如果在 自定义
App
中使用getInitialProps
,则未使用 静态生成 (Static Generation) 的页面将禁用此优化 - 如果在 自定义
Document
中使用getInitialProps
,请确保在假设页面是服务端渲染前检查ctx.req
是否已定义。对于预渲染的页面,ctx.req
会是undefined
- 在路由器的
isReady
字段为true
之前,避免在渲染树中使用next/router
的asPath
值。静态优化页面仅在客户端知道asPath
,服务端并不知晓,因此将其作为 prop 使用可能导致不匹配错误。active-class-name
示例 演示了将asPath
作为 prop 使用的一种方式