vitalizer
nuxt-vitalizer

即刻提升 Google Lighthouse 中的 LCP 分数

Nuxt Vitalizer module

Nuxt Vitalizer

作为一款专注一事Nuxt 模块,它汇集了各种变通方案,旨在优化 Google Lighthouse 和 Google PageSpeed Insights 中的最大内容绘制 (LCP)。

此模块为以下 Nuxt 问题(以及其他问题)提供解决方案

功能

  • 🚀 零配置即可获得更好的 LCP
  • 🫸 移除渲染阻塞 CSS

设置

npx nuxi@latest module add nuxt-vitalizer

使用

将 Nuxt Vitalizer 添加到 Nuxt 配置中即可使用

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer']
})

要自定义模块,请在 Nuxt 配置中配置 vitalizer 选项

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer'],

  vitalizer: {
    // Remove the render-blocking entry CSS
    disableStylesheets: 'entry'
  }
})

LCP 优化功能

应用此模块的优化功能后,您可以获得更高的 Lighthouse 性能分数

Lighthouse SEO performance score when using the module

!注意 此功能默认启用。

大型 Nuxt 应用在 Lighthouse 和 Google PageSpeed Insights 中可能会因 HTML 中累积的 <link rel="prefetch"> 标签而导致性能分数不佳。

对于每个动态导入(例如异步组件和其他资源,如图片),都会渲染一个 prefetch 链接。这会导致浏览器预取这些分块,即使它们在当前页面中不需要。虽然这对于应用的整体性能很有利,但它可能导致大量的预取请求,从而对最大内容绘制分数产生负面影响。

此模块会挂钩到 Nuxt 构建过程,通过禁用动态导入的 prefetch 链接渲染来优化 LCP 分数。

!注意 此功能必须手动启用。

预加载链接用于预加载当前页面所需的关键资源。虽然它们通常在优化网站性能方面有一席之地,但如果使用不当,也可能导致大量的请求。移除预加载链接有助于提高 FCP(首次内容绘制)分数,尤其是在网络条件较差的情况下。

要移除预加载构建资源,请将 disablePrefetchLinks 选项设置为 true

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer'],

  vitalizer: {
    disablePrefetchLinks: true
  }
})

停止渲染阻塞 CSS

!注意 此功能必须手动启用。要使用它,您需要启用 Nuxt inlineStyles 功能。请务必在启用此选项后测试您的应用。

CSS 样式表是渲染阻塞资源,这意味着浏览器必须在渲染页面之前下载并解析 CSS。通过使用内联样式而不是加载样式表,浏览器可以更快地渲染页面,从而提高 LCP 分数。

虽然最新的 Nuxt 版本在 SSR 渲染期间会内联样式,但 entry.<hash>.css 样式表仍会渲染到 HTML 中。这可能导致渲染阻塞 CSS,从而对最大内容绘制分数产生负面影响。

为什么会这样?正如 Nuxt 核心团队成员 @danielroe 所解释的

我认为这是当前内联样式实现的限制。

在您的应用中到处使用的样式可以安全地从 CSS 源中完全移除。但仅在一个组件或页面中使用的 CSS 需要同时存在于 CSS 文件内联样式中。

目前,vite 完全负责在客户端加载 CSS,这意味着即使我们跟踪了哪些 CSS 已经加载,我们也无法阻止 vite 加载包含重复 CSS 的 CSS 文件。

这绝对是我希望看到修复的问题。

首先,尝试在 app.vue 文件中导入主应用样式。当 Nuxt 构建时,它们将保存为 entry CSS 文件

// `app.vue`
import '~/assets/css/main.css'

现在,将 disableStylesheets 选项设置为 entry 以阻止 entry.<hash>.css 样式表在 HTML 中渲染

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer'],

  vitalizer: {
    disableStylesheets: 'entry'
  }
})

模块选项

interface ModuleOptions {
  /**
   * Whether to remove prefetch links from the HTML. If set to `dynamicImports`, only dynamic imports will be removed. To disable all prefetching, such as images, set to `true`.
   *
   * @remarks
   * This will prevent the browser from downloading chunks that may not be needed yet. This can be useful for improving the LCP (Largest Contentful Paint) score.
   *
   * @default 'dynamicImports'
   */
  disablePrefetchLinks?: boolean | 'dynamicImports'

  /**
   * Whether to remove preload links from the HTML. This can be useful for improving the FCP (First Contentful Paint) score, especially when emulating slow network conditions.
   *
   * @default false
   */
  disablePreloadLinks?: boolean

  /**
   * Whether to remove the render-blocking stylesheets from the HTML. This only makes sense if styles are inlined during SSR rendering. To only prevent the `entry.<hash>.css` stylesheet from being rendered, set to `entry`. If set to `true`, all stylesheet links will not be rendered.
   *
   * @remarks
   * This requires to have the Nuxt `inlineStyles` feature enabled. Make sure to test your application after enabling this option.
   *
   * @default false
   */
  disableStylesheets?: boolean | 'entry'
}

💻 开发

  1. 克隆此仓库
  2. 使用 corepack enable 启用 Corepack
  3. 使用 pnpm install 安装依赖
  4. 运行 pnpm run dev:prepare
  5. 使用 pnpm run dev 启动开发服务器

鸣谢

  • 所有在 Nuxt GitHub issues 中启发此模块的讨论和贡献。

许可证

MIT 许可 © 2024-PRESENT Johann Schopplich