自动静态优化
如果页面没有阻塞性数据需求,Next.js 会自动判定该页面是静态的(可预渲染)。这一判定基于页面中是否不存在 getServerSideProps
和 getInitialProps
。
此功能使得 Next.js 能够生成同时包含服务端渲染页面和静态生成页面的混合应用。
静态生成的页面仍然具有响应性:Next.js 会在客户端对应用进行水合 (hydrate),赋予其完整的交互能力。
该功能的主要优势在于,经过优化的页面无需服务端计算,可以直接从多个 CDN 节点即时传输给终端用户。从而为用户带来_极速_的加载体验。
工作原理
如果页面中存在 getServerSideProps
或 getInitialProps
,Next.js 会切换为按需渲染(即 服务端渲染 (SSR))。
如果上述情况不存在,Next.js 将通过预渲染页面为静态 HTML 的方式自动静态优化您的页面。
在预渲染阶段,路由器的 query
对象会是空的,因为在此阶段我们无法提供 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 使用的方案