PageSpeed のルールと推奨事項

このガイドでは、PageSpeed Insights のルールを状況に応じて検討します。つまり、クリティカル レンダリング パスを最適化する際に注意すべき点と、その理由を説明します。

レンダリングをブロックする JavaScript と CSS を排除する

最初のレンダリングまでの時間を最短にするには、ページ上のクリティカル リソースの数を最小限に抑え(可能であれば)排除し、ダウンロードされるクリティカル バイト数を最小限に抑え、クリティカル パス長を最適化します。

JavaScript の使用を最適化する

JavaScript リソースは、async とマークされているか、特別な JavaScript スニペットによって追加されている場合を除き、デフォルトでパーサー ブロックです。パーサー ブロック JavaScript は、ブラウザを強制的に CSSOM で待機させ、DOM の構築を一時停止します。その結果、最初のレンダリングまでの時間が大幅に遅れる可能性があります。

非同期 JavaScript リソースを優先する

非同期リソースを使用すると、ドキュメント パーサーのブロックが解除され、ブラウザはスクリプトを実行する前に CSSOM をブロックする必要がなくなります。多くの場合、スクリプトで async 属性を使用できるということは、それが最初のレンダリングに必須ではないことも意味します。最初のレンダリングの後、スクリプトを非同期で読み込むことを検討してください。

同期サーバー呼び出しを避ける

navigator.sendBeacon() メソッドを使用して、unload ハンドラの XMLHttpRequests によって送信されるデータを制限します。多くのブラウザでは、このようなリクエストの同期が求められるため、ページの遷移が著しく遅くなる可能性があります。次のコードは、unload ハンドラではなく pagehide ハンドラで navigator.sendBeacon() を使用してサーバーにデータを送信する方法を示しています。

    <script>
      function() {
        window.addEventListener('pagehide', logData, false);
        function logData() {
          navigator.sendBeacon(
            'https://putsreq.herokuapp.com/Dt7t2QzUkG18aDTMMcop',
            'Sent by a beacon!');
        }
      }();
    </script>

新しい fetch() メソッドを使用すると、簡単にデータを非同期でリクエストできます。現時点では利用可能な地域がないため、使用前に機能検出を使用してその存在をテストする必要があります。このメソッドは、複数のイベント ハンドラではなく、Promises を使用してレスポンスを処理します。XMLHttpRequest に対するレスポンスとは異なり、フェッチ レスポンスは Chrome 43 以降でストリーム オブジェクトになります。つまり、json() を呼び出すと Promise も返されます。

    <script>
    fetch('./api/some.json')
      .then(
        function(response) {
          if (response.status !== 200) {
            console.log('Looks like there was a problem. Status Code: ' +  response.status);
            return;
          }
          // Examine the text in the response
          response.json().then(function(data) {
            console.log(data);
          });
        }
      )
      .catch(function(err) {
        console.log('Fetch Error :-S', err);
      });
    </script>

fetch() メソッドは POST リクエストを処理することもできます。

    <script>
    fetch(url, {
      method: 'post',
      headers: {
        "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
      },
      body: 'foo=bar&lorem=ipsum'
    }).then(function() { // Additional code });
    </script>

JavaScript の解析を延期する

ブラウザがページをレンダリングする際の作業量を最小限に抑えるため、最初のレンダリング用の可視コンテンツの構築に重要ではないスクリプトは遅らせます。

長時間実行される JavaScript を避ける

JavaScript が長時間実行されると、ブラウザによる DOM の構築、CSSOM の構築、ページのレンダリングがブロックされるため、最初のレンダリングで重要でない初期化のロジックや機能は後日まで処理を延期します。長い初期化シーケンスを実行する必要がある場合は、ブラウザが間に他のイベントを処理できるように、複数のステージに分割することを検討してください。

CSS の使用を最適化する

レンダリング ツリーを構築するには CSS が必要です。多くの場合、JavaScript はページの最初の構築時に CSS をブロックします。重要でない CSS が重要でない CSS としてマークされていることを確認し(印刷媒体やその他のメディアクエリなど)、重要な CSS の量と所要時間をできる限り少なくします。

CSS をドキュメント ヘッドに含める

ブラウザが <link> タグを検出して CSS のリクエストをディスパッチできるように、すべての CSS リソースを HTML ドキュメント内でできるだけ早い段階で指定します。

CSS のインポートを避ける

CSS のインポート(@import)ディレクティブを使用すると、あるスタイルシートで別のスタイルシート ファイルからルールをインポートできます。ただし、このようなディレクティブは、クリティカル パスにラウンドトリップが増えるため、使用は避けてください。インポートされた CSS リソースが検出されるのは、@import ルール自体を含む CSS スタイルシートが受信され、解析された後のみです。

レンダリングをブロックする CSS をインライン化する

パフォーマンスを最大限に高めるには、重要な CSS を HTML ドキュメントに直接インラインで記述することをおすすめします。これにより、クリティカル パスでの余分なラウンドトリップがなくなり、正しく実施すれば、HTML のみがブロッキング リソースとなる「1 往復」のクリティカル パス長を実現できます。

フィードバック