NextJS Core Web Vitals - 移除渲染阻塞 CSS
终极 NextJS Core Web Vitals 指南 - 移除渲染阻塞 CSS

在 NextJS 中移除渲染阻塞 CSS
CSS 是渲染阻塞的。这意味着当浏览器在页面 head 中发现 CSS 时,在所有 CSS 被解析完成之前不会开始渲染。如果浏览器需要下载一个或多个外部 CSS 文件,这可能会占用宝贵的时间。在本文中,我将向你展示如何在 NextJS 应用中移除这些渲染阻塞的 CSS 文件以加速渲染。这将改善你的绘制指标(First Contentful Paint 和 Largest Contentful Paint)
Table of Contents!
默认情况下,NextJS 会为每个页面创建 2 个样式表。第一个是全局样式表,第二个是页面特定的样式表。这会花费我们多少时间?这取决于很多因素,比如访问者的设备、网络速度、网络连接协议、到服务器的距离、样式表的大小等。根据我所有客户在所有设备上的平均数据,我发现这大约需要 200 毫秒。在 NextJS 网站上,在快速 3G 连接下下载这 2 个样式表将需要 600 毫秒。这将使所有绘制指标延迟 600 毫秒。是时候采取行动移除这些渲染阻塞的样式表了!

方案一:生成 Critical CSS
第一个也是最快的方案是生成 Critical CSS。Critical CSS 是渲染页面可见部分所需的 CSS 规则集合。这些规则以内联方式放置在页面的 HEAD 中。然后,浏览器会继续渲染,同时并行下载原始 CSS 文件。一旦原始 CSS 文件下载完成,它们就会被注入到页面中。
Critical CSS 现在已作为实验性功能在 NextJS 中可用。在 NextJS 中生成 Critical CSS 非常简单。只需在 next.config.js 中添加 experimental: { optimizeCss: true },并在项目中安装 critters@0.0.7 作为依赖即可。
const nextConfig = {
reactStrictMode: true,
experimental: { optimizeCss: true }
} 方案二:在页面 HEAD 中内联 CSS
如果你不想在 NextJS 应用中启用实验性功能来改善 Core Web Vitals,你可以考虑内联你的 CSS。你需要创建一个自定义 head 部分并在 _document.tsx 中引用它。
这种方法的缺点是内联 CSS 可能会比第一种方法更大。但是,如果你保持样式表简洁高效,这种方法很可能会显著改善你 NextJS 应用的 Core Web Vitals!
import { Html, Head, Main, NextScript } from "next/document";
import { readFileSync } from "fs";
import { join } from "path";
class InlineStylesHead extends Head {
getCssLinks: Head["getCssLinks"] = ({ allFiles }) => {
const { assetPrefix } = this.context;
if (!allFiles || allFiles.length === 0) return null;
return allFiles
.filter((file: any) => /\.css$/.test(file))
.map((file: any) => (
<style
key={file}
nonce={this.props.nonce}
data-href={`${assetPrefix}/_next/${file}`}
dangerouslySetInnerHTML={{
__html: readFileSync(join(process.cwd(), ".next", file), "utf-8"),
}}
/>
));
};
}
export default function Document() {
return (
<Html>
<InlineStylesHead />
<body>
<Main />
<NextScript />
</body>
</Html>
);
} 方案三:Styled Components
Styled Components 是一个 CSS-in-JS 工具,允许你在 JavaScript 文件中编写 CSS。这有很多优势。例如,你可以复用类名,轻松移除未使用的 CSS 代码,与传统 CSS 文件相比更容易管理代码。对于 Core Web Vitals 来说,这意味着你只会注入该页面所需的样式。相当不错,对吧?
从 NextJS 12.1 版本开始,在 NextJS 应用中使用 Styled Components 比以往更加简单。在 next.config.js 中添加 compiler:{styledComponents: true},安装 styled-components(yarn add styled-components,安装完成后运行 yarn add -D @types/styled-components),更新 _document.js 文件以支持 Styled Components 的服务端渲染,就可以了!
const nextConfig = {
reactStrictMode: true,
compiler: {
styledComponents: true,
}
}import Document, { DocumentContext } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
Urgent Fix Required?
Google Search Console failing? I offer rapid-response auditing to identify the failure point within 48 hours.
- 48hr Turnaround
- Rapid Response
- Failure Identification

