NextJS Core Web Vitals - レンダーブロッキングCSSを削除する
NextJS Core Web Vitals 究極ガイド - レンダーブロッキングCSSを削除する

NextJSでレンダーブロッキングCSSを削除する
CSSはレンダーブロッキングです。つまり、ブラウザはページのheadにCSSを検出すると、そのCSSがすべて解析されるまでレンダリングを開始しません。ブラウザが1つ以上の外部CSSファイルをダウンロードする必要がある場合、貴重な時間がかかる可能性があります。この記事では、NextJSアプリでレンダーブロッキングCSSファイルを削除してレンダリングを高速化する方法を紹介します。これにより、ペイント指標(First Contentful PaintおよびLargest Contentful Paint)が改善されます
Table of Contents!
デフォルトでは、NextJSはページごとに2つのスタイルシートを作成します。1つ目はグローバルスタイルシート、2つ目はページ固有のスタイルシートです。これにどのくらいの時間がかかるでしょうか?それは、訪問者のデバイス、ネットワーク速度、ネットワーク接続プロトコル、サーバーまでの距離、スタイルシートのサイズなど、多くの要因に依存します。私のすべてのクライアントにおいて、すべてのデバイスの平均では、約200msかかることがわかっています。NextJSのウェブサイトでは、高速3G接続でこれら2つのスタイルシートのダウンロードに600msかかります。これにより、すべてのペイント指標が600ms遅延します。これらのレンダーブロッキングスタイルシートを削除する時です!

オプション1: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 }
} オプション2:ページのHEADにCSSをインライン化する。
Core Web Vitalsを改善するためにNextJSアプリで実験的機能を有効にしたくない場合は、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>
);
} オプション3:Styled Components
Styled Componentsは、JavaScriptファイル内にCSSを記述できるCSS-in-JSツールです。これには多くの利点があります。たとえば、クラス名を繰り返し使用でき、未使用の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();
}
}
}
Your dev team is busy.
Delegate the performance architecture to a specialist. I handle the optimization track while your team ships the product.
- Parallel Workflows
- Specialized Expertise
- Faster Delivery

