Skip to main content

自动静态优化

如果页面没有阻塞数据要求,Next.js 会自动确定页面是静态的(可以预渲染)。该确定是通过页面中缺少 getServerSidePropsgetInitialProps 来做出的。

¥Next.js automatically determines that a page is static (can be prerendered) if it has no blocking data requirements. This determination is made by the absence of getServerSideProps and getInitialProps in the page.

此功能允许 Next.js 发出包含服务器渲染页面和静态生成页面的混合应用。

¥This feature allows Next.js to emit hybrid applications that contain both server-rendered and statically generated pages.

静态生成的页面仍然是反应性的:Next.js 将为你的应用客户端提供充足的交互性。

¥Statically generated pages are still reactive: Next.js will hydrate your application client-side to give it full interactivity.

此功能的主要优点之一是优化的页面不需要服务器端计算,并且可以立即从多个 CDN 位置流式传输给终端用户。其结果是为你的用户带来超快的加载体验。

¥One of the main benefits of this feature is that optimized pages require no server-side computation, and can be instantly streamed to the end-user from multiple CDN locations. The result is an ultra fast loading experience for your users.

怎么运行的

¥How it works

如果页面中存在 getServerSidePropsgetInitialProps,Next.js 将切换为根据请求按需渲染页面(即 服务器端渲染)。

¥If getServerSideProps or getInitialProps is present in a page, Next.js will switch to render the page on-demand, per-request (meaning Server-Side Rendering).

如果不是上述情况,Next.js 将通过将页面预渲染为静态 HTML 来自动静态优化你的页面。

¥If the above is not the case, Next.js will statically optimize your page automatically by prerendering the page to static HTML.

在预渲染期间,路由的 query 对象将为空,因为我们在此阶段没有可提供的 query 信息。水合后,Next.js 将触发应用更新,以在 query 对象中提供路由参数。

¥During prerendering, the router's query object will be empty since we do not have query information to provide during this phase. After hydration, Next.js will trigger an update to your application to provide the route parameters in the query object.

水合触发另一个渲染后查询将被更新的情况是:

¥The cases where the query will be updated after hydration triggering another render are:

  • 该页面是 dynamic-route

    ¥The page is a dynamic-route.

  • 该页面的 URL 中有查询值。

    ¥The page has query values in the URL.

  • 重写next.config.js 中配置,因为这些参数可能需要在 query 中解析和提供。

    ¥Rewrites are configured in your next.config.js since these can have parameters that may need to be parsed and provided in the query.

为了能够区分查询是否已完全更新并可供使用,你可以利用 next/router 上的 isReady 字段。

¥To be able to distinguish if the query is fully updated and ready for use, you can leverage the isReady field on next/router.

很高兴知道:使用 动态路由 添加到使用 getStaticProps 的页面的参数将始终在 query 对象内可用。

¥Good to know: Parameters added with dynamic routes to a page that's using getStaticProps will always be available inside the query object.

next build 将为静态优化页面发出 .html 文件。例如,页面 pages/about.js 的结果将是:

¥next build will emit .html files for statically optimized pages. For example, the result for the page pages/about.js would be:

.next/server/pages/about.html

如果你将 getServerSideProps 添加到页面,它将是 JavaScript,如下所示:

¥And if you add getServerSideProps to the page, it will then be JavaScript, like so:

.next/server/pages/about.js

注意事项

¥Caveats

  • 如果你有 定制 AppgetInitialProps,则此优化将在没有 静态生成 的页面中关闭。

    ¥If you have a custom App with getInitialProps then this optimization will be turned off in pages without Static Generation.

  • 如果你有 定制 DocumentgetInitialProps,请确保在假设页面是服务器端渲染之前检查 ctx.req 是否已定义。对于预渲染的页面,ctx.req 将是 undefined

    ¥If you have a custom Document with getInitialProps be sure you check if ctx.req is defined before assuming the page is server-side rendered. ctx.req will be undefined for pages that are prerendered.

  • 避免在渲染树中的 next/router 上使用 asPath 值,直到路由的 isReady 字段为 true。静态优化的页面只知道客户端上的 asPath 而不是服务器上的,因此将其用作 prop 可能会导致不匹配错误。active-class-name 示例 演示了使用 asPath 作为属性的一种方法。

    ¥Avoid using the asPath value on next/router in the rendering tree until the router's isReady field is true. Statically optimized pages only know asPath on the client and not the server, so using it as a prop may lead to mismatch errors. The active-class-name example demonstrates one way to use asPath as a prop.