Skip to main content

Next.js 关键 CSS 提取

在 Next.js 中提取关键 CSS,最推荐的方式是开启内置的 optimizeCss 实验性功能。它基于 Google 的 critters 库实现,能自动完成分析、提取和内联。

⚙️ 方案一:使用内置 experimental.optimizeCss(强烈推荐)

这是 Next.js 官方为解决“消除阻塞渲染的 CSS”这一问题提供的内置方案。

1. 安装依赖 首先,需要将 critters 安装为生产依赖 (dependencies),而非开发依赖 (devDependencies)。这是因为优化在构建时执行,但 Vercel 等平台在生产构建时可能不会安装开发依赖,导致构建失败。

npm install critters
# 或
yarn add critters
# 或
pnpm add critters

2. 配置 next.config.jsnext.config.js 文件中启用 optimizeCss 功能。

/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
optimizeCss: true, // 开启 CSS 优化
},
};

module.exports = nextConfig;

开启后,Next.js 会在构建时自动提取关键 CSS 并将其内联到 HTML 的 <head> 中,同时将剩余 CSS 以非阻塞方式加载。

3. (可选)自定义配置 默认配置能满足大部分需求。如需更精细的控制(例如自定义 critters 选项),可以通过将 optimizeCss 设置为一个配置对象来实现。

🚀 方案二:使用 experimental.inlineCss(实验性)

这是另一个实验性功能,但它会内联所有 CSS,而非仅提取关键路径 CSS。

1. 开启配置 此功能适合 CSS 体积很小的项目(如使用 Tailwind CSS)。但对于 CSS 体积较大的项目(如使用组件库),内联所有 CSS 会显著增加 HTML 体积,反而拖慢加载速度。

/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
inlineCss: true, // 开启所有 CSS 内联
},
};

module.exports = nextConfig;

⚠️ 重要提示

  • App Router 支持experimental.optimizeCss 目前对 App Router 的支持可能不完善,有开发者反馈在 App Router 下无法正常工作。如果你的项目使用 App Router,需要特别留意。
  • SSG 页面处理:对于 SSG(静态生成)页面,可以考虑通过后处理脚本的方式,在构建完成后对所有生成的 HTML 文件运行 critters 进行优化。
  • 开发模式:上述优化功能仅在生产构建 (next build) 时生效,开发模式下 (next dev) 不会生效。

💎 总结

  • 首选方案:对于大部分使用 Pages Router 的项目,experimental.optimizeCss 是集成了 critters 的官方方案,配置最简单。
  • 特殊场景:如果使用 App Router 或需要对优化过程有更精细的控制,可考虑在构建流程中自行集成 critters 库。
  • CSS 体积很小:如果项目主要使用 Tailwind 这类原子化 CSS,可以尝试 experimental.inlineCss,但需注意其全量内联的特性。