Webページのリソース"非最適化"によるPageSpeed Insightsへの詳細な影響調査


2020年6月3日追記

本家レポートよりPageSpeed Insightsのスコア改善が捗る裏レポートツールを公開しました。合わせてご参考ください。
https://simulate.site/cheatspeed-insights/

この記事はLighthouse 5.6に準拠しています。Lighthouse 6.0への変更についてはこちらの記事などをご参考ください。
PageSpeed Insightsのスコア大変動か? Lighthouse 6 で変わる採点ルールを先取りチェック! - アイデアマンズブログ

リソースの非最適化によるPageSpeed Insightsのスコアを左右する要因を検証

通常、Webページの各種リソースの最適化や応答時間を短縮してパフォーマンスを向上させますが、ここではPageSpeed Insightsがそれらをどう評価するか、逆に非最適化することで検証してみました。

結論

リソースの条件を悪化させると、次のようにスコアとその構成要素が変化します。

  スコア SPX※ FCP FMP TTI FCI※
オリジナル 100 100 100 100 100 100
HTMLの応答遅延(9秒) 74 2 100 100 100 100
HTMLの重量化(約2MB) 10 6 1 1 20 12
CSSの応答遅延(9秒) 74 2 100 100 100 100
CSSの重量化(約2MB) 10 6 1 1 20 12
画像の応答遅延(9秒) 74 3 100 100 100 100
画像の重量化(約2MB) 99 96 100 100 100 100
JavaScriptの応答遅延(9秒) 99 96 100 100 100 100
JavaScriptの重量化(約2MB) 73 100 100 100 18 100
JavaScriptの重量化(約2MB)+headに配置 7 1 0 0 17 10
JavaScriptのロングタスク化 53 100 100 100 0 0

※SPX: スピード指標 / ※FCI: 最初のCPUアイドル

  • 通信中のデータ圧縮(Content-Encoding)はなし
  • モバイル端末としてテスト

ダミーページ

こんな感じの極めてシンプルなダミーページを用意します。

<!doctype html>
<html>
  <head>
    <title>テストページ</title>
    <link rel="stylesheet" href="css/normal.css">
    <link rel="stylesheet" href="webfont/normal.css">
  </head>
  <body>
    <h1>Lighthouse Performance Test</h1>
    <img src="images/normal.jpg">
    <p>HTML・CSS・JavaScript・WebFontのPageSpeed Insights(Lighthouse Performance)への影響を比較検証します。</p>
    <script src="js/normal.js"></script>
  </body>
</html>

ブラウザで見るとこんな感じです。

PageSpeed Insightsでスコアを測ると、当然100点となります。

以前、こんな実験も行いました。今回は因果関係をもう少し細かくしてみる試みです。

超シンプルなページでPageSpeedスコア0点を意図的にとる方法 - Qiita

HTML関連

HTMLの応答を9秒遅延させる

単純に9秒Sleepさせます。なぜ9秒かと言うと、10秒だとタイムアウトするからです。

これは以前実験したのですが、ドキュメントTTFBの遅延は、とても重要なのですがスピード指標にしか影響しません。

PageSpeed InsightsでドキュメントTTFBはSpeedIndexにしか影響しない - Qiita

HTMLを約2MBに重量化する

HTMLに非表示のdiv要素を多数追加し、サイズを約2MBまで膨張させます。なぜ2MBかというと、モバイル端末としてのテストは通信速度が1.6Mbpsにエミュレートされるので、2MBだと大体10秒くらいの読み込み時間を要するからです。

これはガッツリすべての項目が下がりました。レンダリング初期段階で大きな遅延が発生するからです。

JavaScriptは変更していないのに、それらの評価系であるTTIFCIも低下しています。これはTTIFCPFCIFMPを計算の基準としているからで、道連れを食らった結果です。

CSS関連

HTMLと同様に、CSSの応答を9秒遅らせるケースと、CSSをダミーのセレクタで2MBに膨張させたケースです。

CSSを2MBに膨張させると、HTMLの膨張とほぼ同じ結果となりました。CSSの読み込み中もレンダリングが停止するからです。

一方、CSSの応答を遅らせるケースではSPXにのみ影響があります。ダウンロードが開始されたどうかが評価に影響するのが興味深いです。

画像関連

画像データのレスポンスをサーバー上でのSleepにより9秒遅らせるケースと、解像度を大きく上げて2MB程度までデータサイズを膨張させたケースです。

画像の応答が遅いとSPXが大きく低下しますが、画像データが膨張した場合はスコアの低下がほとんどありません。こちらもファーストビューの描画を評価するSPXには影響がありそうなものですが、予想外の結果でした。

JavaScript関連

JavaScriptの応答を9秒遅らせる

ダウンロードの開始(JavaScriptのTTFB)をサーバー上で9秒遅らせても、スコアにほとんど影響がありません。CSSのように、リソースのダウンロードが始まるまでが遅いことと、始まってからが遅いことには評価の違いがあります。

この結果は意外でした。応答が始まらないということは、サーバー側のタイムアウトの可能性があるものとして、評価対象のタイムラインに乗ってこない…という感じでしょうか。

ただ、CSSやJavaScriptのような静的リソースが応答遅延するというのはレアケースだと思うので、今後なにかの機会にまた調べようと思います。

JavaScriptを約2MBに重量化する

ダミーのfunctionを多数追加してデータサイズを膨張させます。TTIは悪化していますが、表示系の評価指標は無傷です。これはscript要素がHTMLの最下部であり、レンダリングがブロックされるものの、ページの表示に関わる処理はほとんど完了しているからでしょう。

使ってないJavaScriptは積極的に削除しないといけません。

同じJavaScriptの負荷を評価するFCIに影響がないのも予想外でした。

仮説のひとつは、TTIはネットワークコネクションの沈静化も計測している点がFCIと異なります。なのでTTIはJavaScriptの読み込みにより後ろ倒しになり、FCIは早々に要件を満たしたと評価される…というものですが、ネットワークコネクションの沈静化は2本以下になることが条件で、それはJavaScriptの読み込み時点で満たしているはずなのです。

もうひとつの仮説は、TTIがJavaScriptの実行開始を起点とするが(読み込み完了を待つか)、FCIはそうではない…というものです。

これも真相は掴めず仕舞いですが、またの機会に。

JavaScriptを約2MBに重量化してhead要素に移動

レンダリングを初動でがっつりブロックして、JavaScriptとしての負荷も増大させるのでこれがおそらく最低スコアを出すだろう…と予想通りの結果に。

外部JavaScriptを(asyncdeferなしに)HTMLの上部に書くというのは枯れたアンチパターンのはずですが、それでも頻繁に見かけます。

この通り、PageSpeedスコアには甚大な影響があります。

JavaScriptのロングタスク化

メインスレッドを500ms専有するロングタスクを100msおきに約20秒間、繰り返します。

表示系の評価は無傷ですが、JavaScript負荷系のTTIFCIは狙い通り0点になりました。

ページ自体ではパフォーマンスに気をつけていても、ビジネス上必要な広告や解析系のサードパーティースクリプトがガンガンロングタスクを発生させるケースがかなり多いです。

ちょうどGoogleが重い広告をブロックする方向にあるというニュースがありましたが、

「Chrome」、過剰に「重い」広告をブロックへ--8月から - CNET Japan

各社サードパーティスクリプトもロングタスクを生じさせない品質を担保してほしいものです。