CSS の配信を最適化する

このルールは、レンダリングをブロックする外部スタイルシートがページに含まれていて、最初のレンダリング時間を遅らせていることを PageSpeed Insights が検出した場合にトリガーされます。

概要

ブラウザでは、コンテンツを表示する前に、現在のページのスタイルとレイアウトの情報をすべて処理する必要があります。このため、ブラウザは外部スタイルシートがダウンロードされて処理されるまでレンダリングをブロックします。ダウンロードには複数のラウンド トリップが必要となることがあり、最初のレンダリング時間が遅くなります。 クリティカル レンダリング パスについて詳しくは、レンダリング ツリーの構築、レイアウト、ペイントをご覧ください。レンダリングがブロックされないようにし、CSS の配信を改善する方法については、レンダリング ブロック CSS をご覧ください。

推奨される解決方法

外部 CSS リソースが小さい場合は、HTML ドキュメントに直接挿入できます。これをインライン化といいます。小さい CSS をこのようにインライン化すると、ブラウザはページのレンダリングに進むことができます。なお、CSS ファイルが大きい場合、CSS を完全にインライン化すると、PageSpeed Insights から、ページをスクロールせずに見える範囲が大きすぎるとの警告が出る場合があります(スクロールせずに見える範囲のコンテンツのサイズを削減するをご覧ください)。大きな CSS ファイルの場合は、スクロールせずに見える範囲のコンテンツの表示に必要な CSS を特定してインライン化し、残りのスタイルの読み込みはスクロールせずに見える範囲のコンテンツの表示後まで遅らせる必要があります。

小さな CSS ファイルのインライン化の例

次のような HTML ドキュメントがあるとします。
<html>
  <head>
    <link rel="stylesheet" href="small.css">
  </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
また、リソース small.css が次のようになっているとします。
  .yellow {background-color: yellow;}
  .blue {color: blue;}
  .big { font-size: 8em; }
  .bold { font-weight: bold; }
この場合、重要な CSS を次のようにインライン化できます。
<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
    <noscript id="deferred-styles">
      <link rel="stylesheet" type="text/css" href="small.css"/>
    </noscript>
    <script>
      var loadDeferredStyles = function() {
        var addStylesNode = document.getElementById("deferred-styles");
        var replacement = document.createElement("div");
        replacement.innerHTML = addStylesNode.textContent;
        document.body.appendChild(replacement)
        addStylesNode.parentElement.removeChild(addStylesNode);
      };
      var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
      if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
      else window.addEventListener('load', loadDeferredStyles);
    </script>
  </body>
</html>

重要な CSS と重要ではない CSS の判別、重要な CSS のインライン化、重要ではない CSS の遅延読み込みを伴うこの変換は、nginx、Apache、IIS、ATS、および OpenLightSpeed 用の PageSpeed Optimization モジュールprioritize_critical_css フィルタを有効にすれば自動的に行うことができます。

また、CSS の非同期読み込みに便利な loadCSS 関数もご覧ください。この関数は、ウェブページから重要な CSS を抽出するツールである Critical と連携できます。

スクロールせずに見える範囲のコンテンツのスタイル設定に用いられる重要なスタイルがインライン化され、すぐにドキュメントに適用されます。small.css 全体は、ページが最初に表示された後で読み込まれます。small.css のスタイルは読み込みが完了するとページに適用されます。その結果、重要なコンテンツを最初に表示する処理がブロックされなくなります。

今後、ウェブ プラットフォームで JavaScript を用いずに HTML Imports を使用して、レンダリングをブロックすることなくスタイルシートを読み込めるようになる予定です。

大きなデータ URI をインライン化しない

CSS ファイル内のデータ URI をインライン化するときは注意してください。CSS で入念に選んだ小さなデータ URI を使用することは問題ありませんが、大きなデータ URI をインライン化すると、スクロールせずに見える範囲の CSS のサイズが大きくなり、ページが表示されるまでの時間が遅くなる場合があります。

CSS 属性をインライン化しない

コードの不要な重複につながる場合があるため、HTML 要素に CSS 属性(<p style=...>など)をインライン化するのはできるだけ避けてください。また、HTML 要素への CSS のインライン化は、コンテンツ セキュリティ ポリシー(CSP)によってデフォルトでブロックされます。