【Nuxt3系列十四】预渲染

428 阅读2分钟

Nuxt允许在构建时渲染静态页面,以提高性能和SEO指标

在构建额时候,允许选择某些页面进行预渲染,然后在运行时,返回这个预渲染的页面,而不用在运行时再进行生成一遍。

基于爬取的预渲染

使用nuxi generate命令来构建预渲染的应用。这个命令类似于设置了nitro.static选项为truenuxt build命令,或者是nuxt build --prerender

运行这个命令之后,Nitro就像是爬虫一样,首先是访问根页面/以及与之链接的所有页面。依此类推,不断的访问。而被访问到的页面,将会被预渲染。

你可以将.output/public目录部署到任何的静态托管服务上。或者使用npx server .output/public在本地进行预览。

Nitro的爬虫具体的工作原理如下:

  1. 加载应用的根路由的html,一级pages目录中任何非动态页面,还有nitro.prerender.routers数组中的其它路由。
  2. 将html和payload.json保存到~/.output/public/目录中,以静态的方式提供服务。
  3. 查找HTML中的所有超链接,导航到其他路路由
  4. 对于每个超链接重复步骤1~3,直到没有新的超链接

未链接到可发现页面的页面无法被自动预渲染。

选择性预渲染

你可以手动指定Nitro在构建过程中需要获取和预渲染的路由,或者在 nuxt.config 文件中忽略那些你不想预渲染的路由,例如 /dynamic

export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ["/user/1", "/user/2"],
      ignore: ["/dynamic"],
    },
  },
});

你可以将此与 crawlLinks 选项结合使用,以预渲染爬虫无法发现的一组路由,例如你的 /sitemap.xml/robots.txt

export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,
      routes: ["/sitemap.xml", "/robots.txt"],
    },
  },
});

设置 nitro.prerendertrue 类似于将 nitro.prerender.crawlLinks 设置为 true

最后,你可以在routeRules中手动配置

export default defineNuxtConfig({
  routeRules: {
    // Set prerender to true to configure it to be prerendered
    "/rss.xml": { prerender: true },
    // Set it to false to configure it to be skipped for prerendering
    "/this-DOES-NOT-get-prerendered": { prerender: false },
    // Everything under /blog gets prerendered as long as it
    // is linked to from another page
    "/blog/**": { prerender: true },
  },
});

同样,你也可以在页面中定义(需要开启experimental.inlineRouterRules配置)

<script setup>
// Or set at the page level
defineRouteRules({
  prerender: true,
});
</script>

<template>
  <div>
    <h1>Homepage</h1>
    <p>Pre-rendered at build time</p>
  </div>
</template>

运行时渲染

prerenderRoutes

你可以在程序运行的时候,指定他添加更加多的路由进行预渲染

<script setup>
prerenderRoutes(["/some/other/url"]);
</script>

<template>
  <div>
    <h1>This will register other routes for prerendering when prerendered</h1>
  </div>
</template>

prerender:routes Nuxt hook

这个hook将会在进行预渲染之前进行调用

export default defineNuxtConfig({
  hooks: {
    async "prerender:routes"(ctx) {
      const { pages } = await fetch("https://api.some-cms.com/pages").then(
        (res) => res.json(),
      );
      for (const page of pages) {
        ctx.routes.add(`/${page.name}`);
      }
    },
  },
});

prerender:generateNuxt hook

在预渲染期间,每个路由都会调用这个方法。你可以使用它来细粒度地处理预渲染的每个路由。

export default defineNuxtConfig({
  nitro: {
    hooks: {
      "prerender:generate"(route) {
        if (route.route?.includes("private")) {
          route.skip = true;
        }
      },
    },
  },
});