クリティカルでない CSS を遅延させる

Demián Renzulli
Demián Renzulli

CSS ファイルはレンダリング ブロック リソースです。ブラウザがページをレンダリングする前に、読み込んで処理する必要があります。スタイルシートが不必要に大きいウェブページは、レンダリングに時間がかかります。

重要でない CSS を遅延させてクリティカル レンダリング パスを最適化し、ファースト コンテンツフル ペイント(FCP)を改善する方法について説明します。

CSS の読み込みが最適でない

次の例には、3 つの非表示のテキスト段落を含むアコーディオンが含まれています。各段落は異なるクラスでスタイル設定されています。

このページは 8 つのクラスを含む CSS ファイルをリクエストしますが、表示されるコンテンツのレンダリングに必要なのはそのうちの一部だけです。

このガイドの目的は、このページを最適化して、重要なスタイルのみを同期的に読み込み、残りのスタイル(段落スタイルなど)を非ブロッキング方式で読み込むようにすることです。

測定

DevTools で Lighthouse を実行して、影響の大きい指標を確認します。

  1. Chrome でデモを開きます
  2. Chrome DevTools を開きます
  3. [パフォーマンス パネル] を選択します。
  4. パネル内でページを再読み込みします。

レポートには、指標「初回コンテンツの描画」の値が「1 秒」と表示され、改善策「レンダリングをブロックするリソースを排除する」が style.css ファイルを指しています。

最適化されていないページの Lighthouse レポート。FCP が「1 秒」で、「機会」に「ブロックしているリソースを排除する」が表示されている
Lighthouse レポートでは、ページの読み込み速度を上げるためにスタイルシートを簡素化することが推奨されています。

結果のトレースでは、CSS の読み込みが完了した直後に FCP マーカーが配置されます。

最適化されていないページの DevTools パフォーマンス トレース。CSS の読み込み後に FCP が開始されている。
最適化されていないデモページでは、CSS の読み込みが完了するまで FCP は発生しません。

つまり、ブラウザは、画面に 1 つのピクセルを描画する前に、すべての CSS が読み込まれて処理されるのを待つ必要があります。

最適化

このページを最適化するには、カバレッジ ツールを使用して、どのクラスがクリティカルと見なされるかを判断します。

  1. Control+Shift+P または Command+Shift+P(Mac)を押して、デベロッパー ツールのコマンド メニューを開きます。
  2. 「カバレッジ」と入力して、[カバレッジを表示] を選択します。
  3. [再読み込み] をクリックしてページを再読み込みし、カバレッジのキャプチャを開始します。
CSS ファイルのカバレッジ。未使用のバイト数が 55.9% であることが示されています。
カバレッジ レポートには、CSS のうち、ページの初回読み込みで実際に使用されている部分の割合が表示されます。

レポートをダブルクリックすると、詳細が表示されます。

  • 緑色のクラスは重要です。ブラウザは、タイトル、サブタイトル、アコーディオン ボタンなどの表示コンテンツをレンダリングするために、これらの要素を必要とします。
  • 赤でマークされたクラスは重要ではなく、非表示の段落など、すぐに表示されないコンテンツにのみ影響します。

この情報を使用して、ブラウザがページの読み込み直後に重要なスタイルを処理し、重要でない CSS を後回しにできるように CSS を最適化します。

  1. カバレッジ レポートで緑色でマークされたクラス定義を抽出し、それらのクラスをページの先頭の <style> ブロックに配置します。

    <style type="text/css">
    .accordion-btn {background-color: #ADD8E6;color: #444;cursor: pointer;padding: 18px;width: 100%;border: none;text-align: left;outline: none;font-size: 15px;transition: 0.4s;}.container {padding: 0 18px;display: none;background-color: white;overflow: hidden;}h1 {word-spacing: 5px;color: blue;font-weight: bold;text-align: center;}
    </style>
    
  2. 次のパターンを適用して、残りのクラスを非同期で読み込みます。

    <link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link rel="stylesheet" href="styles.css"></noscript>
    

これは CSS を読み込む標準的な方法ではありません。仕組みは次のとおりです。

  • link rel="preload" as="style" はスタイルシートを非同期でリクエストします。preload について詳しくは、重要なアセットをプリロードするガイドをご覧ください。
  • linkonload 属性により、スタイルシートの読み込みが完了したときにブラウザで CSS を処理できます。
  • onload ハンドラの使用後に「null」に設定すると、一部のブラウザで rel 属性を切り替える際にハンドラが再呼び出しされるのを防ぐことができます。
  • noscript 要素内のスタイルシートへの参照は、JavaScript を実行しないブラウザのフォールバックを提供します。

本番環境

本番環境では、この動作をカプセル化し、ブラウザ間で適切に動作する loadCSS などの CSS 遅延関数を使用することをおすすめします。これらの関数は コンテンツ セキュリティ ポリシーをサポートしています。このポリシーでは、インライン onload JavaScript が許可されない場合があります。

CSS リンクをページの下部に配置することもできます。これにより、ブラウザでスタイルシートが読み込まれるのを待たずにコンテンツをレンダリングできます。ただし、ブラウザは依然としてスタイルシートを優先するため、ブラウザで重要なコンテンツがブロックされる可能性があります。

ほとんどのスタイルが非同期で読み込まれても、結果のページは以前のバージョンとまったく同じように表示されます。

モニタリング

DevTools を使用して、最適化されたページで別のパフォーマンス トレースを実行します。

FCP マーカーは、ページが CSS をリクエストする前に表示されます。つまり、ブラウザは CSS が読み込まれるまで待つ必要がなく、ページをレンダリングできます。

最適化されたページの DevTools パフォーマンス トレース。CSS の読み込み前に FCP が開始されていることが示されています。
最適化されたページでは、スタイルシートが読み込まれる前に FCP が開始されることがあります。

最後のステップとして、最適化されたページで Lighthouse を実行します。

レポートでは、FCP ページが 0.2 秒短縮されたことがわかります(20% の改善です)。

Lighthouse レポート。FCP 値が「0.8 秒」と表示されている。

[レンダリングを妨げるリソースの除外] の提案は、[改善できる項目] に表示されなくなり、[合格した監査] セクションに表示されるようになりました。

Lighthouse レポートの図。[合格した監査] セクションに [レンダリングをブロックするリソースを排除する] が表示されています。
これで、ページはブロック リソースの監査に合格します。

次のステップと参考資料

より複雑な本番環境については、重要な CSS を抽出するガイドで、重要な CSS を抽出するための最も一般的なツールの一部を紹介しています。また、それらのツールが実際にどのように機能するかを確認するためのCodelab も含まれています。