公開日: 2018 年 8 月 17 日
このガイドでは、PageSpeed Insights のルールをコンテキストに沿って説明します。つまり、クリティカル レンダリング パスを最適化する際に注意すべき点とその理由について説明します。
レンダリングを妨げる JavaScript と CSS を排除する
最初のレンダリング時間を短縮するには、ページ上の重要なリソースの数を最小限に抑え、可能であれば排除し、ダウンロードされる重要なバイト数を最小限に抑え、クリティカル パスの長さを最適化します。
JavaScript の使用を最適化する
JavaScript リソースは、async
としてマークされているか、特別な JavaScript スニペットを使用して追加されている場合を除き、デフォルトでパーサーによってブロックされます。パーサーが JavaScript をブロックすると、ブラウザは CSSOM を待機し、DOM の作成を一時停止します。これにより、最初のレンダリングまでの時間が大幅に遅れる可能性があります。
非同期 JavaScript リソースを優先する
非同期リソースはドキュメント パーサーのブロックを解除し、ブラウザがスクリプトを実行する前に CSSOM でブロックされないようにします。スクリプトで async
属性を使用できる場合、多くの場合、最初のレンダリングに必須ではないことを意味します。最初のレンダリング後にスクリプトを非同期で読み込むことを検討してください。
同期サーバー呼び出しを避ける
navigator.sendBeacon()
メソッドを使用して、unload
ハンドラで XMLHttpRequest によって送信されるデータを制限します。多くのブラウザでは、このようなリクエストを同期させる必要があるため、ページ遷移が遅くなることがあります。次のコードは、navigator.sendBeacon()
を使用して、unload
ハンドラではなく pagehide
ハンドラでサーバーにデータを送信する方法を示しています。
<script>
function() {
window.addEventListener('pagehide', logData, false);
function logData() {
navigator.sendBeacon(
'https://putsreq.herokuapp.com/Dt7t2QzUkG18aDTMMcop',
'Sent by a beacon!');
}
}();
</script>
fetch()
メソッドは、データを非同期でリクエストするより良い方法を提供します。fetch()
は、複数のイベント ハンドラではなく Promise を使用してレスポンスを処理します。XMLHttpRequest に対するレスポンスと異なり、fetch()
レスポンスはストリーム オブジェクトです。つまり、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 をドキュメント ヘッドに含める
ブラウザが <link>
タグを検出して CSS のリクエストをできるだけ早く送信できるように、HTML ドキュメント内ですべての CSS リソースをできるだけ早く指定します。
CSS のインポートを回避する
CSS インポート(@import
)ディレクティブを使用すると、1 つのスタイルシートから別のスタイルシート ファイルにルールをインポートできます。ただし、これらのディレクティブはクリティカル パスに追加のラウンドトリップを導入するため、使用しないでください。インポートされた CSS リソースは、@import
ルールを含む CSS スタイルシートが受信されて解析された後にのみ検出されます。
レンダリングをブロックする CSS をインライン化する
最適なパフォーマンスを得るには、重要な CSS を HTML ドキュメントに直接インライン化することを検討してください。これにより、クリティカル パスでの追加のラウンドトリップが排除され、正しく行えば、HTML のみがブロック リソースとなる「1 回のラウンドトリップ」のクリティカル パス長を実現できます。