PageSpeed Insights の使い方とパフォーマンス最適化

PageSpeed Insights とは

PageSpeed Insights とはページのパフォーマンスを測定するためのオンラインツールです。PageSpeed Insights は測定するツールに Lighthouse を使用します。Lighthouse とは、より集中的なページのパフォーマンステストを実行できるツールで、Chrome の拡張機能か Google Chrome 52 以降の DevTools に組み込まれています。

PageSpeed Insights のスタート画面
PageSpeed Insights のスタート画面

PageSpeed Insights の測定はオンラインで実施できるため、ソフトウェアのインストールなどは一切必要ありません。PageSpeed Insights のページの画面中央にあるフォームに測定したい URL を入力し、"分析" ボタンをクリックするだけで簡単にパフォーマンスを測定できます。

PageSpeed Insights の測定結果画面
PageSpeed Insights の測定結果画面

PageSpeed Insights のパフォーマンス結果は 0 ~ 100 ポイントの間で評価され、スコアが高いほどパフォーマンスが高いことを示します。ただし、PageSpeed Insights のテスト内容は継続的に改良されているため、評価されたスコアは将来的に変化する場合があります。

パフォーマンスの重要性

ページのパフォーマンスは非常に重要です。ページの読み込み時間が短くなることでユーザに与えるストレスを軽減し、Google からも評価されるメリットがあります。逆にページの読み込み時間が遅い場合、表示の完了を待たずにユーザが離脱する可能性があります。Google や Amazon などは、どの程度のパフォーマンスがユーザに影響するのか統計的に求めています。

  • サイトの表示が 0.5 秒遅くなると、検索数が 20 % 減少する。(Google)
  • サイトの表示が 0.1 秒遅くなると、売り上げが 1 % 減少し、1 秒高速化すると 10 % の売上が向上する。(Amazon)
  • サイトの表示が 1 秒遅くなると、ページビューが 11 %、コンバージョンが 7 %、顧客満足度が 16 % 低下する。(Aberdeen Group)

また、Web ユーザビリティの第一人者であるヤコブ・ニールセン博士は、Website Response Times で次のように述べています。

  • 0.1 秒までのなら応答が瞬時に返ってきたという印象を与える。
  • 1 秒までならユーザーの思考は途切れなく流れる。
  • 10 秒までならユーザーの注意力は続く。
  • 10 秒以上遅延してしまうと、ユーザーが即、サイトから離れてしまうことも多くなる。

ただし、上記の評価はインターネットの回線速度が非常に遅い時代の評価であり、現代ではユーザは 10 秒も待ってくれません。どんなに遅くてもユーザが許容できる待ち時間は、わずか数秒程度です。なぜなら、ユーザの問題を解決することが書かれているサイトは無数に存在するからです。あなたのサイトのパフォーマンスが遅ければ、他の速いサイトに行けば解決します。それほどまでにユーザは急いでおり、 パフォーマンスはユーザが離脱する原因に直結します。

PageSpeed Insights の測定結果

測定結果のページには大きく分けて 3 種類の結果が表示されます。赤色で表示される "修正が必要な問題点"。橙色で表示される "修正を考慮する問題点"。緑色で表示される "ルールに合格した項目" です。下記は、Yahoo!Japan を例にサイトパフォーマンスを測定した結果画面です。

測定結果のページに表示される優先度インジケータ
スケール説明
赤色 0~49 (遅い)この問題を修正すると、ページのパフォーマンスが大幅に改善されます。
橙色 50~89 (平均)それほど忙しくない場合はこの問題の修正を検討してください。
緑色 90~100 (速い)大きな問題は見つかりません。パフォーマンスは良好です。
PageSpeed Insights の測定結果画面
PageSpeed Insights の測定結果画面

修正を行う場合、赤色の問題点から着手しましょう。修正が難しい場合は、橙色の修正を検討して下さい。次章からは、具体的な修正手順について説明します。

複数のページリダイレクトの回避

この問題は、ページ内に 2 つ以上のリダイレクトがある場合に発生します。

ページにアクセスがあった場合、他のリソースにリダイレクトすることはページの読み込み速度を遅くします。もしも、複数のリダイレクトがあれば、その分だけ遅延します。リダイレクトの設定は、通常サーバの .htaccess などの設定ファイルに定義されています。オンラインサービスを利用している場合は、それらの設定ファイルのアクセス権限がない代わりに GUI で操作できるサービスもあります。ただし、セキュリティ上の都合で、それらのファイルへのアクセスを拒否している場合もあります。

ブラウザは、リダイレクト先のページをリクエストすると、サーバは以下の HTTP レスポンスを返します。その後、ブラウザはリソースをリダイレクト先から取得するために、新しく HTTP リクエストを行います。このようなネットワーク通信回数の増加は、リソースの読み込みを 100 ms 以上遅くする可能性があります。

HTTP/1.1 301 Moved Permanently
Location: /path/to/new/location
リダイレクト先をリクエストした場合の HTTP レスポンス例

この問題の解決方法は、Lighthouse レポートに一覧表示されたリダイレクトされているリソースを修正することです。具体的には、リダイレクトが発生しないようにリンクをリダイレクト先に更新してください。リンクをリダイレクト先に更新すると、リダイレクトは発生しなくなります。

.htaccess の設定方法は「.htaccessの書き方」を参照してください。

サーバー応答時間の短縮 (TTFB)

この問題は、リクエストに対してサーバから最初のレスポンス (Time To First Byte) が 600 ms 以上かかる場合に発生します。

サーバの応答時間が遅いことはページの読み込み時間が長くなる原因のひとつです。サーバは、ブラウザのリクエストに応えるためにバックエンドで様々な処理を行います。しかし、サーバの性能が悪い場合、それらのリクエストに対するレスポンスを返すまでに時間がかかる場合があります。原因は CPU やメモリのハードウェアかもしれませんし、Apache や Nginx、データベース、アプリケーションなどかもしれません。

この問題の解決方法は、サーバの性能をアップグレードする、またはサーバの性能が良いプラットフォームに移転することです。サーバのレスポンスが遅い原因は様々な要因が考えられるため、パフォーマンスの測定や、ボトルネックの改善は専門的な知識を必要とします。もしも専門的な知識がない場合は、サポートに相談するか、プラットフォームのアップグレード、または移転を検討してください。

オフスクリーン画像の遅延読み込み

この問題は、ページを読み込むときにスクロールしなければ見えない部分 (オフスクリーン) の画像が読み込まれている場合に発生します。厳密には、ユーザがそのページを操作可能になる状態 (Time To Interactive:TTI) イベントの前にオフスクリーン画像が読み込まれることで監査が失敗します。

オフスクリーンは、ページを読み込んでもユーザは見ることができません。ページの読み込みがすべて完了するまでユーザは操作ができないため、オフスクリーンの部分が大きいほど体感時間が増加します。ユーザの体感時間を上げるためには、最初にユーザが見える部分だけを読み込ませ、オフスクリーン部分は遅延読み込みする方法があります。

この問題の解決方法は、最初のリクエストにオフスクリーン画像を含めないことです。また、画像だけでなく HTML, CSS, Javascript などにも適用することで読み込み時間をさらに短縮することができます。読み込みのタイミングを管理するためには IntersectionObserver を使用します。IntersectionObserver は、ブラウザの見える範囲 (ViewPort) に要素が入ったタイミングでイベントを発火させることができる技術です。例えば、scroll イベントをフックし、getBoundingClientRect() によって画面の絶対座標を取得することで、読み込みをコントロールします。

var io = new IntersectionObserver(
  entries => {
    console.log(entries);
  },
  {
    /* Using default options. Details below */
  }
);
// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();
IntersectionObserver の例

レンダリングを妨げるリソースの除外

この問題は、以下の 3 種類のブロックリソースのいずれかを検出したときに発生します。

  • 以下の <script> タグ
    • head 内にある場合
    • defer 属性を持たない場合
    • async 属性を持たない場合
  • 以下の <link rel="stylesheet">タグ
    • disabled 属性を持たない場合
    • ユーザのデバイスに対応する media 属性がない場合
  • 以下の <link rel="import">タグ
    • async 属性を持たない場合

上記の問題点は、検出した時点でレンダリングがブロックされるリソースであるため、ブロックされた時間分だけ表示の完了が遅延します。レンダリングのブロックについては、クリティカルレンダリングパスについて説明している「CSS パフォーマンス最適化」の記事を参照してください。

この問題の解決方法は、レンダリングをブロックするリソースをインライン化することです。

<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js">
  </head>
  <body>
    Hello, world!
  </body>
</html>
レンダリングをブロックするリソースを読み込んでいる例
<html>
  <head>
    <style> body{color:blue;} </style>
    <script> /* JavaScript */ </script>
  </head>
  <body>
    Hello, world!
  </body>
</html>
レンダリングをブロックするリソースをインライン化した例

その他の解決方法としては、CSS の読み込みに preload を指定したり、javascript がページの読み込みを妨げないように非同期読み込みを行う方法があります。以下のように CSS には <link> タグに rel 属性を付与し、Javascript には <script> タグに async 属性、または defer 属性を使用します。これらの属性は、ページのレンダリングをブロックして遅延させることを回避し、最適なパフォーマンスを実現します。

<link rel="preload" src="style.css">
<script async src="script1.js">
<script defer src="script2.js">
preload 属性と async 属性と defer 属性を付与した例

ただし、preload は IE や Firefox など、一部のブラウザでは対応していないため注意が必要です。また、preload は CSS を非同期で読み込むため、アクセス直後のレンダリングが一瞬崩れたように表示されてしまう問題があります。preload 時の FOUC (Flash of Unstyled Content) 問題を回避するには、クリティカルレンダリングパスを最適化する必要があります。詳細は「クリティカルなリクエストの深さの最小化」の章を参照してください。

async 属性と defer 属性のいずれも指定しない状態では同期読み込みになります。この場合、HTML パーサーが <script> タグに到達すると、スクリプトをダウンロードして実行します。スクリプトの実行中は、それ以降のレンダリングがブロックされ HTML パーサーは一時停止します。スクリプトが完了すると、HTML パーサーは再び解析を行います。

async 属性が付与された場合、非同期読み込みになります。この場合、HTML パーサーが <script> タグに到達すると、スクリプトのダウンロードが平行して行われます。ダウンロードが完了すると、HTML パーサーは一時中止し、スクリプトの実行を行います。スクリプトが完了すると、HTML パーサーは再び解析を行います。

defer 属性が付与された場合、非同期読み込みになります。この場合、HTML パーサーが <script> タグに到達すると、スクリプトのダウンロードが平行して行われます。しかし、ダウンロードが完了してもスクリプトは実行されず、HTML パーサーは解析を続けます。すべての解析が完了した時点でスクリプトが実行されます。

async vs defer 属性
async vs defer 属性

上記のパターンでは、何も指定しないデフォルトの状態がもっとも遅くなります。async 属性と defer 属性はどちらが速いのかはスクリプトのサイズ、実行タイミング、終わるまでの処理時間が異なるので、一概には言えません。重要なポイントは、スクリプトの処理内容に合った適切な属性を指定することです。

使用していない CSS の遅延読み込み

この問題は、重要ではない CSS が検出されたときに発生します。重要ではない CSS とは、ページの読み込みにおいてダウンロードされる CSS の中で、カバレッジ率 (網羅率) が低い CSS のことです。カバレッジ率が低い CSS とは、ページ内で使われていない CSS ルールが多く定義されている CSS ファイルを指します。ただし、重要ではない CSS ファイルであっても Lighthouse では 2 KB 未満の CSS ファイルは無視されます。

ページを構成するための必要最低限な CSS はクリティカル CSS と呼ばれます。重要ではない CSS ファイルは、クリティカル CSS 以外のファイルになります。余計な CSS ファイルを読み込むことは余分なネットワークトリップを発生させ、使われていなくても CSS ルールが適用されるか確認するために無駄な計算を行うことになります。

この問題の解決方法は、CSS ファイルをインライン化することです。可能であれば、クリティカル CSS ファイルのみをインライン化し、使われていない CSS ルールは除去できるかを検討してください。

<html>
  <head>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    Hello, world!
  </body>
</html>
CSS ファイルを読み込んでいる例
<html>
  <head>
    <style> body{color:blue;} </style>
  </head>
  <body>
    Hello, world!
  </body>
</html>
CSS ファイルをインライン化した例

効率的な画像フォーマット

この問題は、PNG や JPEG の画像形式が使われており、もっと効率的な画像形式 (JPEG 2000、JPEG XR、WebP など) が使われていない場合に発生します。最適化された画像が使われていない場合、より多くのデータをダウンロードすることになります。Lighthouse は、ページ上のすべての画像を収集し、圧縮レベルを 85 に設定してから前後比較を行います。その結果、差分が 4 KB 以上であれば最適化されていると判断します。

この問題の解決方法は、ページ上で使われている画像を最適化することです。より最適化された画像を配信するためには WebP 形式も検討してください。WebP 形式の画像を使用することは、「次世代フォーマットでの画像の配信」の監査に合格するための条件になります。最適な画像を配信するための詳細は、「画像最適化戦略」を参照してください。

次世代フォーマットでの画像の配信

この問題は、画像形式が Google が開発しているオープンソースの WebP 形式が使用されていない場合に発生します。Lighthouse は、ページ上のBMP, JPEG, PNG 画像を収集し、WebP に変換してから前後比較を行います。その結果、差分が 8 KB 未満であれば次世代フォーマットでの画像の配信されていると判断します。

WebP は JPEG や PNG から変換可能であり、より優れた圧縮率と品質特性を持つ画像形式です。ただし WebP 形式は、その他の画像形式と比べて良好なパフォーマンスを示しますが、すべてのブラウザでサポートされていない問題があります。

この問題の解決方法は、次世代フォーマットである WebP 形式を用意して定義することです。WebP 形式の詳細や変換方法については、「画像最適化戦略」を参照してください。

カスタム速度の記録と計測

この問題は、監査の合格や不合格を判定するものではありません。単純にパフォーマンスを計測するための API を紹介するための項目になります。そのため、警告のアイコンが表示されていても最終的なスコアに影響はありません。警告アイコンを消すためには、カスタム速度を計測するための API を埋め込む必要があります。

パフォーマンスを計測するための APIとは、カスタム速度を計測するための API (User Timing API) を指します。User Timing API は、Javascript のパフォーマンスを、極めて高い精度で計測することができる API です。今までは、ms 精度での計測が主流でしたが、高精度時計 (High Resolution Time) が登場したことで 1,000 倍の µs 精度で計測することが可能です。

User Timing API は performance オブジェクトによりいくつかのメソッドを提供します。測定したい箇所に任意の名前を付けて mark し、mark 間の経過時間を measure で計測します。User Timing API の詳細は、MDN などのサイトを参照してください。以下は、User Timing API で計測する簡単なサンプルです。

performance.mark('start');

/* 計測したい Javascript の処理 */

performance.mark('end');
performance.measure('UserTiming', 'start', 'end');

console.log(performance.getEntriesByType('mark'));
console.log(performance.getEntriesByType('measure'));
User Timing API のサンプル

ウェブフォント読み込み中のテキストの表示

この問題は、ウェブフォントが読み込まれ表示されるまでの間、ユーザが他の代替フォントでテキストが見れない場合に発生します。

ウェブフォントは CSS で @font-face を使用することで利用可能です。ユーザのデバイスがフォントを持っていれば問題ありませんが、フォントを持っていない場合はダウンロードする時間がかかります。特に日本語フォントの場合、使われている文字数の関係からファイルサイズが大きくなります。もしもダウンロードが完了するまで、代替フォントによるテキストの表示がなされない場合、空白の画面のまま待機することになります。

ウェブフォントのダウンロードスケジュールは、CSS において font-display プロパティによって制御することができます。font-display プロパティの値は、以下の 5 つのいずれかを選択します。

  • auto:フォントの表示戦略はユーザーエージェントが定義します。(デフォルト値)
  • block:フォントに対して短いブロック期の後、永続的にスワップ期を置きます。
  • swap:フォントに対して非常に短いブロック期の後、永続的にスワップ期を置きます。
  • fallback:フォントに対して非常に短いブロック期の後、短いスワップ期を置きます。
  • optional:フォントに対して非常に短いブロック期の後、スワップ期を置きません。
@font-face {
  font-family: ExampleFont;
  src: url(/path/to/fonts/examplefont.woff) format('woff'),
  font-display: fallback;
}
ウェブフォントの設定例

ウェブフォントが表示されるまでの挙動は UX を損ねる場合があり、どの値を取るべきかはサイトの戦略次第になります。一般的には、swapfallback が選ばれる傾向にあります。font-display プロパティを用いた戦略については、以下のサイトを参照してください。

この問題の解決方法は、font-display プロパティに適切な値を設定し、ウェブフォントが表示されるまでの挙動を改善することです。

メインスレッド処理の最小化

この問題は、Javascript の解析、コンパイル、実行にかかる時間が大きい場合に発生します。Lighthouse が出力したレポートには、カテゴリとかかった時間が表示されているため、何がボトルネックとなっているのかが分かります。

メインスレッド処理の最小化の監査結果
メインスレッド処理の最小化の監査結果

Javascript は多くの処理を行えるため、CSS で制御するべきアニメーションなども記述できます。しかし、Javascript は基本的にシングルスレッドで動作するため、CSS でも行えるような処理をスクリプト側で実装してしまうと、その分だけスレッドを独占します。

この問題の解決方法は、ボトルネックとなっているメインスレッド上の処理をチューニング、またはリファクタリングすることです。レンダリングの邪魔にならないように、初期表示に不要な処理は遅延読み込みさせたり、何かしらのイベント発火にしてください。

静的なアセットと効率的なキャッシュポリシーの配信

この問題は、静的なアセット (フォント、画像、メディアファイル、スクリプト、スタイルシート) が効率的な Cache-Control を設定されていない場合に発生します。Cache-Control とは、ブラウザがサーバに対してリソース (例えば画像ファイルなど) を要求する際に、ある一定期間はダウンロードをしないキャッシュの仕組みです。つまり、画像ファイルなどはテキストファイルとは異なり変化しないリソースであるため、毎回ダウンロードする必要はありません。例えば、サーバはブラウザに対して最初にダウンロードした画像は1年間 (31,536,000 秒) キャッシュしておくように指示することができます。

 Cache-Control: max-age=31536000
サーバから1年間キャッシュするための HTTP レスポンスヘッダー

長時間キャッシュするように指示された場合、ブラウザはローカルにファイルを保存しておきます。そして、次回同じファイルをリクエストする場合に、キャッシュ時間内であれば、ダウンロードせずにローカルのファイルを参照します。ダウンロードするよりもローカルのファイルを参照した方が速いため、効率的なキャッシュはページの読み込み速度を短縮することができます。

変化しないリソースは、静的なアセット (資産) と呼ばれます。フォントや画像などは不変の静的アセットであるため、長時間キャッシュできます。しかし、キャッシュの時間内はブラウザ側でクリアしない限りアセットが更新されないため、サーバのファイルを入れ替えても古いアセットが表示され続ける点には注意が必要です。キャッシュについては、「キャッシュによるパフォーマンスを向上させる方法」を参照してください。また適切な HTTP キャッシュ戦略については、以下を参照してください。

この問題の解決方法は、静的なアセットに効率的なキャッシュを割り当てることです。どのファイルに、どれだけのキャッシュ期間を割り当てるべきかは、ファイルやサイトの特性に左右されるため一概には言えません。本サイトの数値は以下となりますので、参考にしてください。

.html  : なし
.css   : Cache-Control: max-age=604800
.js    : Cache-Control: max-age=604800
.png   : Cache-Control: max-age=15552000
.svg   : Cache-Control: max-age=15552000
.ico   : Cache-Control: max-age=15552000
.woff  : Cache-Control: max-age=15552000
.xml   : なし
.txt   : なし
.json  : なし
murashun.jp のキャッシュポリシー

JavaScript の実行にかかる時間の低減

この問題は、スクリプトの実行時間が長い場合に発生します。Lighthouse が出力したレポートには、各スクリプトのファイル名と解析時間、処理時間、合計時間が表示されているため、何のスクリプトがボトルネックとなっているのかが分かります。

JavaScript の実行にかかる時間の低減の監査結果
JavaScript の実行にかかる時間の低減の監査結果

ユーザが画面の操作が可能になるには、Javascript のメインスレッドが完了する必要があります。そのため、メインスレッド上で大量のコードが実行されると、ユーザの操作できるまでの時間が伸びてしまうため、体感速度が低下します。また、Javascript が大量のメモリを消費する場合、メモリ不足によって操作しにくい状態になります。もしも、メモリリークが発生すると、ページは完全にフリーズしてしまう可能性があります。Javascript 起動最適化の詳細については、以下を参照してください。

この問題の解決方法は、コードのチューニング、またはリファクタリングです。ユーザが必要とするコードのみを送信し、コードの縮小や圧縮、または未使用のコードの削除を検討してください。変更しないコードについてはキャッシュを利用することでネットワークトリップを減らすこともできます。

クリティカルなリクエストの深さの最小化

この問題は、監査の合格や不合格を判定するものではありません。Lighthouse から出力されたレポート情報は、ページの読み込み速度を改善するために利用できます。

クリティカルなリクエストの深さの最小化の監査結果
クリティカルなリクエストの深さの最小化の監査結果

上記の画像は Yahoo! のサンプルです。ページのクリティカルリクエストチェーンは、/ (m.yahoo.co.jp) から各ファイルにパスが展開されており、そのうち 2 つのパスは別のチェーンになっています。チェーンのスコアは、末端のファイルの数で決まるため、この場合のスコアは 14 件になります。

チェーンには、リソース毎のダウンロード時間とバイト数の内訳も表示されています。そのため、クリティカルリクエストチェーンは、クリティカルレンダリングパスを最適化するための重要なレポートになります。このレポート情報を参考に、クリティカルなリソース数を最小化や削減、ダウンロード時間の短縮や、遅延や非同期、またはラウンドトリップ数の削減を行います。このような最適化を行うことで、ページの読み込み速度を上げることができます。

クリティカルレンダリングパスについては、「CSS パフォーマンス最適化」、もしくは下記の記事を参照してください。

適切なサイズの画像

この問題は、画像が適切なサイズで指定されていない場合に発生します。Lighthouse は、レンダリングされた画像のサイズをデバイスのピクセル比も考慮に入れた上で実際の画像のサイズと比較します。その結果、差分が 25 KB 以下の場合、適切なサイズの画像ではないと判断します。

デバイスに合わせた適切な画像サイズにするためには、レスポンシブデザインに対応する必要があります。レスポンシブデザインでは、画面の ViewPort に合わせて縦横の比率を CSS の @media (メディアクエリ) によって変更します。

SVG 画像の場合はベクタ形式であるため、画像を劣化させずに任意の大きさに変更できます。ベクタ形式で表現できるラスタ形式の画像を使っている場合は、SVG 画像で代替できるかを検討してください。

この問題を解決方法は、ページで使用している画像をデバイスの解像度を考慮したレスポンシブデザインに対応させます。詳細は、「画像最適化戦略」を参照してください。

CSS の最小化

この問題は、CSS が最小化 (Minify) されていない場合に発生します。Lighthouse は CSS のコメント文や空白文字について最小化できるかどうかを検証します。ただし、Lighthouse の検証は控えめなものであり、より優れた最小化ツールで出力された CSS の方がファイルサイズが少ない場合があります。

この問題の解決方法は、CSS を最小化することです。CSS を最小化するためのツールはオンラインサービスを含めて様々なものがあります。詳細は、「CSS パフォーマンス最適化」を参照してください。

JavaScript の最小化

この問題は、Javascript が最小化 (Minify) されていない場合に発生します。

この問題の解決方法は、Javascript を最小化することです。よりファイルサイズを縮小するためには、専門的な知識を必要としますが難読化という方法があります。難読化は最小化よりも優れたパフォーマンスを発揮しますが、コードに破壊的な変更を加えるために圧縮前のコードに厳密な制限をかけています。それらの制限が守られていないコードは難読化を実施できません。もしも専門的な知識がない場合は、最小化の実施だけにとどめておくべきです。

最小化、または難読化するためのツールは、以下の記事を参照してください。Google が公開している Closure Compiler という Javascript の難読化ツールも以下の記事にリンクがあります。

テキスト圧縮の有効化

この問題は、テキストタイプのリソースが圧縮されていない場合に発生します。Lighthouse は、テキストタイプのリソースを GZIP で圧縮し、前後比較を行います。その結果、差分が 1.4 KB 未満、または 10 % 未満の場合、テキストの圧縮は有効であると判断します。

サーバに対してリソースを要求する場合、HTTP のリクエストヘッダーの accept-encoding には、ブラウザがサポートしている圧縮エンコードリストが含まれています。サーバは、それらのいずれかの圧縮エンコードを選択し、レスポンスヘッダーの content-encoding で、どの形式を使用したのかを通知します。以下は、 gzip 形式で圧縮したリソースを返した例になります。

content-encoding レスポンスヘッダの例
content-encoding レスポンスヘッダの例

この問題の解決方法は、テキスト圧縮を有効にすることです。詳細は、「gzip 圧縮によるサイトパフォーマンスを向上させる方法」を参照してください。

必須のドメインへの事前接続

この問題は、Resources Hints で行う投機的な処理が含まれていない場合に発生します。Resources Hints で行う投機的な処理とは、リンク先へ事前接続を行うことです。つまり、クリックする前からリンク先の読み込み処理を行うことで、クリックしてからの処理速度を短縮させることができる技術です。Resources Hints で行う投機的な処理には、以下の 4 つがあります。

  • dns-prefetch:ページ読み込み時の DNS ルックアップを事前に行う。
  • preconnect:ページ読み込み時の TCP 接続を事前に行う。
  • prefetch:ページ読み込み時のリソースダウンロードを事前に行う。
  • prerender:ページ読み込み時のレンダリング処理を事前に行う。

Resources Hints で行う投機的な処理の記述は以下のとおりです。

<link href="https://foo.example.com" rel="dns-prefetch">
<link href="https://bar.example.com" rel="dns-prefetch">

<link href="https://example.com" rel="preconnect">

<link href="script.js" as="script" rel="prefetch">
<link href="image.png" as="image" rel="prefetch">

<link href="https://example.com/next.html" rel="prerender">
Resources Hints で行う投機的な処理の記述例

この問題の解決方法は、上記のように Resources Hints で行う投機的な処理を記述することです。詳細は、以下の記事を参照してください。

キーリクエストのプリロード

この問題は、クリティカルチェーンにおいて CSS や Javascript が含まれており、preload 属性が付与されていない場合に発生します。クリティカルチェーンは、「クリティカルなリクエストの深さの最小化」の項目を参照してください。

以下のように preload 属性を付与されたリソースは優先的にダウンロードされます。「必須のドメインへの事前接続」の項目で説明した Resources Hints で行う投機的な処理に似ていますが、振る舞いは異なります。Resources Hints で行う投機的な処理は、まだ接続されていないページ外のリソースに対して事前に接続を行います。一方で preload 属性は、ページ内のリソースに対して優先度を上げる目的で使用されます。つまり、Resources Hints で行う投機的な処理はリンク先の事前接続ですが、preload 属性はクリティカルチェーンにおいて優先的にダウンロードされます。

<head>
  ...
  <link rel="preload" href="styles.css" as="style">
  <link rel="preload" href="script.js" as="script">
  ...
</head>
preload 属性を付与した例

この問題の解決方法は、上記のようにクリティカルチェーン上にあるリソースに対して preload 属性を付与することです。

アニメーションコンテンツでの動画フォーマットの使用

この問題は、サイズの大きい GIF をアニメーションコンテンツの配信方法として選択している場合に発生します。アニメーション GIF は品質、フレームレート、再生時間によって MB 単位のファイルサイズになります。アニメーション GIF のサイズは、DevTools を用いることでサイズを確認することができます。

この問題の解決方法は、サイズの大きなアニメーション GIF を他の形式に変換してファイルサイズを縮小することです。他の形式とは、例えば MPEG4 や WebM 形式などです。これらの形式は、品質を劣化させずにファイルサイズを縮小することができます。

アニメーション GIF から他の効率的な形式に変換するためにはいくつかのツールがあります。変換ツールや、ツールの使い方などの詳細は、以下の記事を参照してください。

過大なネットワークペイロードの回避

この問題は、ページのリソース合計が大きすぎる場合に発生します。Lighthouse は、ページの合計サイズが 1,600 KB 以上である場合、サイズが大きすぎると判断します。

一般的なページでリソースの大半を占めているのは、画像や動画ファイルです。それらのリソースをどのように配信するかは 2 つの戦略があります。

この問題の解決方法のひとつは、画像のファイルサイズを圧縮などによって最適化することです。詳細は、「画像最適化戦略」を参照してください。

もうひとつの解決方法は、リソースが必要になるまで読み込みを延期させるアプローチである PRPL パターンとすることです。PRPL パターンは、ブラウザの読み込み処理を適切にスケジューリングすることで細かく読み込み、一度に大量のリソースを読み込まない方法です。低速域のネットワークしか利用できない場合、またはモバイル端末などにコンテンツを配信する場合、PRPL パターンは有効である可能性があります。PRPL パターンの詳細は、以下の記事を参照してください。

過大な DOM サイズの回避

この問題は、ページの DOM サイズが大きすぎる場合に発生します。Lighthouse は、ページに含まれる DOM ノード数が 1,500 以上、またはノードの深さが 32 以上、またはノード数が 60 以上を持つ親ノードがある場合、DOM サイズが大きすぎると判断します。

サイズの大きな DOM は、多くのメモリを消費し、スタイルの計算に時間がかかり、レイアウトにおけるリフローのコストが大きくなります。詳細は、「CSS パフォーマンス最適化」を参照してください。

この問題の解決方法は、ノードを削除してください. ノードの削除ができない場合は、レンダリングパフォーマンスを向上させるために CSS セレクタを単純化させてください。

まとめ

PageSpeed Insights は 2018 年 11 月に Lighthouse を用いてパフォーマンスをテストするように UI を含めて大幅な変更がありました。本ページでは、Lighthouse の監査に失敗した場合の問題、および解決方法について提示しています。

ページのパフォーマンスの向上は、ユーザビリティの向上に大きく寄与するだけでなく、SEO にも良い影響を与えます。ただし、検出された問題の中には専門的な知識が必要になり、改修が非常に難しい問題も含まれます。無理に修正をすることだけを考えずに、サイトを運用していく上でのメンテナンス性も併せて考慮しましょう。

Category:
パフォーマンス
公開日:
更新日:
Pageviews:
6,935
Shares:
53
Tag:
PageSpeed Insights
Lighthouse
Google
SEO
hatebu icon
hatebu