Google Lighthouseは、開発者の間でWebページのパフォーマンスをゲーム化し、促進する最も効果的な方法の1つです。Lighthouseを使えば、全体的なパフォーマンス、アクセシビリティ、SEO、Googleが考える「ベストプラクティス」に基づいてWebページを評価することができます。
これらのテストは、フロントエンドフレームワークのすぐに使えるパフォーマンスを評価したり、熱心なリファクタリングによってパフォーマンスが改善されたことを喜んだりするのに使うかもしれません。そして、Lighthouseの満点のスクリーンショットをソーシャルメディアで共有するのが好きなのはご存じでしょう。紙吹雪のお祝いにふさわしい栄誉です。
Lighthouseが私たちのような開発者にパフォーマンスについて語らせるという事実だけでも勝利です。しかし、パーティーの片棒を担ぐようなことはしたくないですが、実際のところ、Webパフォーマンスはこれよりもはるかに微妙なものです。
この記事では、Google Lighthouseがどのようにパフォーマンス・スコアを算出しているかを検証し、この情報を使って、私たちに有利になるようにスコアを「ハック」してみます。Lighthouseをどこまで 「騙す 」ことができるか、そして自分たちにふさわしいスコアよりも良いスコアを出すことができるか、楽しみながらやってみましょう。
その前に、データについて話しましょう。
現場データは重要である
ローカル・パフォーマンス・テストは、Webサイトのパフォーマンスが正しい方向に傾いているかどうかを理解するための素晴らしい方法ですが、現実の全体像を描くことはできません。WWW(ワールドワイドウェブ)は西部の荒野であり、人々がWebサイトにアクセスするために使用しているさまざまなデバイスの種類、インターネット接続速度、画面サイズ、ブラウザ、およびブラウザのバージョン(これらすべてがページパフォーマンスとユーザー体験に影響を与える可能性があります)を、私たちはほぼ確実に見失っています。
Sentryのようなアプリケーションパフォーマンス監視ツールによって、実際にWebサイトを使用している人々のデバイスから収集されたフィールドデータ(しかも大量に)は、制御された条件下でハイスペックなスーパーパワー開発マシンを使用して、1サンプルサイズから収集されたラボデータよりもはるかに正確なWebサイトパフォーマンスのレポートを提供します。フィリップ・ウォルトンは2021年、HTTPアーカイブのデータに基づき、「Lighthouseで100点を獲得したページのほぼ半数が、推奨されるCore Web Vitalsのしきい値を満たしていなかった」と報告しています。
パフォーマンスとは、単一のCore Web Vitals指標やLighthouseのパフォーマンススコア以上のものです。私たちが話しているのは、扱う生データの種類をはるかに超えるものです。
Webパフォーマンスは数字以上のもの
Webパフォーマンスについて話すとき、スピードが最初に話題に上ることがよくあります。これは測定する上で最悪なことではありませんが、スピードはおそらくビジネスのKPIや売上目標に大きく影響されることを念頭に置かなければなりません。
Googleが2018年に発表したレポートによると、ページの読み込み時間が3秒以上になると、直帰する確率が32%増加し、10秒になると123%に跳ね上がるといいます。
つまり、より多くの売上につなげるには、直帰率を減らす必要があるという結論になります。そして、直帰率を減らすには、ページの読み込みを速くしなければなりません。
しかし、「読み込みを速くする」とはどういうことなのでしょうか?
ある時点で、Webページの読み込みをこれ以上速くすることは物理的に不可能になります。人間やそれをつなぐサーバーは世界中に散らばっており、現代のインターネット・インフラは一度に多くのバイト数しか配信できないのです。
要するに、ページの読み込みは一瞬ではないということです。スピードとは何か?Googleのいう、ページ読み込みイベントとは。
単一の指標では完全には捉えられない体験のことです。ユーザーが「速い」と感じるかどうかには、読み込み体験の間に複数の瞬間があり、1つの瞬間だけに注目すると、残りの時間に起こる悪い体験を見逃してしまうかもしれません。
ここでのキーワードは『体験』です。本当のWebパフォーマンスとは、数字やスピードよりも、ユーザーとしてページロードやページの使いやすさをどのように体験するかということなのです。そしてこれは、Google Lighthouseがどのようにパフォーマンススコアを計算するかという議論にうまくつながっていく。(あなたが思っているよりも、純粋なスピードは重要ではありません)。
Google Lighthouseのパフォーマンススコアはどのように計算されますか?
(CLS))と、ページ読み込みのタイムライン全体を通して観察可能なその他のスピード関連メトリクス(Speed Index (SI)、Total Blocking Time (TBT))に基づくスコアを加重平均して算出されます。
このように、メトリクスは総合スコアで重み付けされます。
各スコアに割り当てられた重み付けは、Googleが優れたユーザー体験のさまざまな構成要素にどのような優先順位をつけているかを教えてくれます。
1. Webページはユーザーの入力に反応しなければならない
この指標は、FCP(First Contentful Paint)後の合計時間を調べ、メインスレッドがユーザー入力への迅速な応答を妨げるほど長くブロックされている可能性がある場所を示すのに役立ちます。メイン スレッドで JavaScript タスクが 50 ミリ秒以上実行されると、メイン スレッドは「ブロックされた」と見なされます。TBTを最小化することで、Webページが物理的なユーザー入力(例:キーの押下、マウスのクリックなど)に確実に反応するようになります。
2.Webページは、予期せぬ視覚的な変化を伴うことなく、有用なコンテンツを読み込むべきである
Lighthouseのメトリクスで次に重みがあるのは、Largest Contentful Paint(LCP)とCumulative Layout Shift(CLS)です。LCPは、ページのロードタイムラインの中で、ページのメインコンテンツがロードされた可能性が高い時点を示すもので、そのため有用です。
メインコンテンツがロードされた可能性が高い時点で、ユーザーがページを使用でき、予期しないビジュアルシフト(CLS)の影響を受けないように、ビジュアルの安定性も維持したいものです。良いLCPスコアは2.5秒未満です(私たちはWebサイトを可能な限り高速化しようとしていることが多いので、これは想像以上に高いスコアです)。
3.Webページは何かを読み込む
First Contentful Paint (FCP) メトリクスは、ユーザーが画面上に何かを見ることができるページロードのタイムライン上の最初のポイントを示し、Speed Index (SI) は、ページが「完了」するまでの時間にわたって、ページロード中にコンテンツが視覚的に表示される速さを測定します。
あなたのページは、HTTPアーカイブのパフォーマンスデータを使用した実際のWebサイトのスピードインデックスに基づいてスコアリングされます。優れたFCPスコアは1.8秒未満、優れたSIスコアは3.4秒未満です。これらのしきい値はどちらも、スピードについて考える際に予想されるよりも高いものです。
速さよりも使いやすさを優先
Google Lighthouseのパフォーマンス・スコアリングは、間違いなくスピードよりもユーザビリティを重視しています。SI(Speed Index)とFCP(First Contentful Paint)は非常に速くても、LCP(Largest Contentful Paint)の描画に時間がかかりすぎ、大きな画像や外部コンテンツの読み込みに時間がかかり、視覚的に状況が変化することでCLSが発生した場合、FCPのレンダリングに多少時間がかかってもCLS(Cumulative Layout Shift)が発生しないページよりも、全体的なパフォーマンススコアは低くなります。最終的に、JavaScriptがメインスレッドを50ms以上ブロックしているためにページが応答しない場合、パフォーマンススコアは、ページがFCPを描くのが少し遅い場合よりも低下します。
各メトリクスの重み付けが最終的なパフォーマンススコアにどのように貢献するかをより詳しく理解するには、Lighthouse Scoring Calculatorのスライダーで理解することができます。
Google Lighthouse の総合的なパフォーマンス スコアは、HTTP アーカイブの実際のWebサイトパフォーマンスデータのパフォーマンス指標から作成された対数正規分布である Lighthouse スコア分布のどの位置に該当するかによって、各指標値を 0 ~ 100 のスコアに変換して算出されます。この数学的にオーバーロードされた情報からは、主に2つのことが読み取れます。
- Lighthouseのパフォーマンススコアは、単独ではなく、実際のWebサイトのパフォーマンスデータに対してプロットされる。
- スコアリングには対数正規分布が使用されているため、個々の指標値と総合スコアの関係は非線形である。つまり、低パフォーマンスのスコアを大幅に改善することは非常に簡単だが、すでに高いスコアを改善することは難しくなる。
Developer.chrome.comでは、対数正規分布曲線の視覚化など、メトリックスコアの決定方法について詳しく説明しています。
Google Lighthouseを 「騙す 」ことは可能か?
GoogleがWebパフォーマンスの話題において、純粋なスピードよりもユーザビリティに重点を置いていることは評価できます。
これは開発者に、生の数字を目指すのではなく、私たちが構築する実際の体験についてもっと考えるよう促している証拠です。
とはいえ、2024年の今日、Google Lighthouseを騙して、ユーザビリティや利便性の点で悪いページを『「実は素晴らしいページだ」と信じ込ませることは可能なのだろうか』と考えたこともあります。
白衣と科学ゴーグルを着用して調査してみました。テストはすべて実施しました。
- Chromium Lighthouseプラグインを使用する
- Arcブラウザのシークレットウィンドウで試す
- 「ナビゲーション」と「モバイル」設定を使用(別記の場合を除く)する
- 私自身による、研究室での使用(つまり、フィールドデータ無し)
とはいえ、私の管理されたテスト環境が、この記事の冒頭で述べた私のアドバイスと矛盾していることは十分承知しています。
この記事から読み取っていただきたいのは、Lighthouseのスコアは、非常に大きく複雑なWebパフォーマンスのほんの一部分に過ぎないということです。
そして実際のデータがなければ、このようなことが重要かどうかはわからないということです。
FCPとLCPのスコアをハックする方法
TL;DR: Lighthouseのテストが終わるまで、FCPとLCPのスコアを上げるために、LCPに適格なコンテンツを最小限の負荷で見せる。
FCPは、ページロードのタイムラインの中で、ユーザーが画面上に何かを見ることができる最初のポイントを示し、LCPは、ページロードのタイムラインの中で、メインページのコンテンツ(すなわち、最大のテキストまたは画像要素)がロードされた可能性が高いポイントを示します。速いLCPは、ページが有用であることをユーザーに安心させるのに役立ちます。「Likely」と「useful」がここで留意すべき重要な言葉です。
何がLCP要素としてカウントされるか
LCPのためにLighthouseが考慮するWebページの要素の種類は以下の通りです。
- <img> 要素
- <svg>要素内の<image>要素
- <video>要素
- url()関数を使って読み込まれた背景画像を持つ要素(CSSグラデーションではない)
- テキストノードや他のインラインレベルのテキスト要素を含むブロックレベル要素
以下の要素は、有用なコンテンツを含まない可能性が高いため、LCPの検討対象から除外します。
- 不透明度がゼロの要素(ユーザーに見えないため)
- viewport全体を覆う要素(背景要素である可能性が高いため)
- プレースホルダー画像やその他のエントロピーが低い画像(すなわち、無地の画像のように情報量が少ない)
画像やテキスト要素が有用であるという概念は、この場合、完全に主観的なものであり、一般的にマシンコードが確実に判断できる範囲外のものです。
例えば、<h1>要素しかないページを作ってみたところ、10秒後にJavaScriptがより説明的なテキストをDOMに挿入し、<h1>要素を非表示にしました。
Lighthouseはこの実験で、見出し要素をLCP要素とみなします。
この時点で、ページのロードタイムラインは終了していますが、メインコンテンツは読み込まれていません。
Lighthouseは、見出しをフルストップなどの句読点に置き換えても、100点満点を与えています。
このテストは、クライアントサイドJavaScriptでページのコンテンツをロードする必要がある場合、ページにより多くの要素をロードする必要があるため、スケルトン・ローダー画面の表示を避けたいことを示唆しています。
また、この処理には時間がかかることがわかっているので、メインスレッドからWebワーカーにネットワークリクエストをオフロードして、TBTに影響を与えないようにすることもできます。こうすることで、Lighthouseに、そのページが実際よりも早くユーザーに役立つものであるという印象を与えることができます。
必要なのは、FCPとしてカウントされる何かを含む有効なLCP要素を含めることだけです。
2024年にクライアントサイドのJavaScriptでメインページのコンテンツをロードすることは決してお勧めしませんが(代わりにCDNから静的HTMLを提供するか、サーバー上にできるだけ多くのページを構築してください)、Lighthouseのパフォーマンススコアが何を示すかにかかわらず、優れたユーザー体験のためにこの「ハック」をお勧めすることは絶対にありません。この方法は、検索エンジンがサイトをインデックスする際にも有利にはなりません。
さらに、LCPを象徴するさまざまなランダム画像を使って、ページの使い勝手をさらに悪くする実験もしてみました。
しかし、ファイルサイズを小さくし、サードパーティの画像APIを使用して「次世代」画像フォーマットに変換し、ページの読み込み速度を向上させたため、Lighthouseはこれらの画像を「プレースホルダー画像」または「エントロピーの低い画像」と解釈したようです。その結果、これらの画像はLCP要素として除外され、LCPがハックされにくくなりました。
デモページを表示し、シークレット・ウィンドウでChromium DevToolsを使用して、結果を確認してください。
しかしこのハックは、おそらく他の多くのユースケースでは持ちこたえられないでしょう。例えば、Discordは、ブラウザでアプリをハードリフレッシュするときに「スプラッシュ・スクリーン」アプローチを使用しており、29という悲しいパフォーマンス・スコアを獲得しています。
私のDOMインジェクションデモと比較すると、LCP要素は、スプラッシュ・スクリーンのコンテンツ自体に含まれる要素ではなく、スプラッシュ・スクリーンの背後にあるコンテンツとして計算されました。Lighthouseのスコアは、認証の後ろにあるアプリにとってはそれほど重要ではないという意見もあります。
アプリがユーザー生成コンテンツを提供する場合、特に画像に関しては、LCPエレメントを完全に制御することができない可能性があります。
例えば、Webページ上のすべての画像のサイズをコントロールできる場合、レントパスのケースのように、興味深いハックや「最適化」(非常に大きな引用符で囲む)を利用して、システムを恣意的に操作できるかもしれません。
2021年、RentPathの開発者は、Webページの画像サムネイルのサイズを大きくすることで、Lighthouseのパフォーマンススコアを17ポイント向上させることに成功しました。彼らはLCP要素を、JavaScriptによる読み込みにかなり時間がかかるページ上のGoogle Mapタイルではなく、より大きなサムネイルの1つとして計算するようLighthouseを説得しました。
要するに、LCPエレメントを意識してコントロールすれば、RentPathや私のようなハッキングであれ、現実的な改善であれ、Lighthouseのパフォーマンススコアを上げることができるということです。
とはいえ、この記事ではスプラッシュスクリーンのアプローチをハックと表現しましたが、だからといってこのタイプの体験が目的を持った楽しい体験を提供できないというわけではありません。パフォーマンスとユーザー体験は、ページロード中に何が起こっているかを理解することであり、それはまた意図することでもあります。
CLSのスコアをハックする方法
TL;DR: レイアウトシフトを引き起こすコンテンツのロードは、Lighthouse のテストが終了するまで延期させる。transformを使用したCSSアニメーションは、DOMへの新しい要素の追加と組み合わせて使用する場合を除き、CLSを引き起こさない。
CLSは10進数で測定され、良いスコアは0.1未満、悪いスコアは0.25を超えます。Lighthouseは、viewportサイズと2つのレンダリングフレーム間のviewport内の不安定な要素の移動の組み合わせに基づいて、ユーザーがページを閲覧している間に発生する予期せぬレイアウトシフトの最大バーストからCLSを計算します。
単発的なレイアウトシフトはそれほど重要ではありませんが、大量のレイアウトシフトが次から次へと発生すると、スコアに悪影響を及ぼします。
ページロード時にレイアウトシフトが発生することが分かっている場合は、ページのロードイベントが完了するまでレイアウトシフトを延期し、Lighthouse に CLS が発生していないと誤認させることができます。
例えば、私が作成したこのデモページでは、JavaScript がすぐに新しいテキスト要素の追加を開始し、元のコンテンツを上にずらしたにもかかわらず、CLS スコアは 0.143 となっています。DOMに新しいノードを追加するJavaScriptをsetTimeout()で任意の5秒だけ一時停止することで、LighthouseはCLSを捕捉しません。
この他のデモページは、ユーザーとのインタラクションなしに、追加された要素が一見ランダムにポップインされることを考えると、間違いなく最後のページよりも使い勝手が悪いにもかかわらず、パフォーマンススコアは100点です。
ページのロードテストのためにレイアウトシフトイベントを遅延させることは可能ですが、このハックは、フィールドデータと時間経過に伴うユーザ体験(先に議論したように、これはより重要な焦点です)に対しては間違いなく機能しません。
レイアウトシフトを遅延させたページで Lighthouse の 「タイムスパン」 テストを実行すると、Lighthouse は 0.186 程度の非グリーン CLS スコアを正しく報告します。
デモのようなカオスな体験を意図的に作り出したいのであれば、CSS アニメーションとトランスフォームを使用することで、より意図的にコンテンツをページ上に表示させることができます。GoogleのCLSガイドでは、「ある位置から別の位置へ徐々に自然に移動するコンテンツは、多くの場合、ユーザが何が起こっているのかをより理解しやすくし、状態が変化する間にユーザを誘導するのに役立つ」と述べられており、ここでもコンテキストにおけるユーザー体験の重要性が強調されている。
次のデモページでは、CSS transform を使用してテキスト要素を 0 から 1 に拡大縮小し、ページ内を移動させています。ページがロードされたとき、テキストノードはすでに DOM 内にあるため、transform は CLS をトリガーすることができません。とはいえ、JavaScript によってページがロードされた後、プログラムによってテキストノードが DOM に追加され、アニメーション化された場合、Lighthouse は確かに CLS を検出し、それに応じてスコアリングを行うことが確認できました。
スピード指数のスコアをハックすることはできない
スピードインデックスのスコアは、ページが読み込まれる際の視覚的な進行状況に基づいています。ページロードのタイムラインの最初のほうにあるコンテンツほど速く読み込まれます。
ページ読み込みのタイムラインが実際よりも遅いと思わせるために、スピードインデックスを騙すハックをすることは可能です。逆に、コンテンツを実際より速く読み込んでいるように 「偽装 」する方法はありません。スピードインデックスのスコアを上げる唯一の方法は、できるだけ早く、できるだけ多くのページを読み込むようにWebページを最適化することです。2024年のWebの状況では、まったく現実的ではありませんが(主に、デザイナーが失業してしまうからです)、Speed Indexを可能な限り下げるために、次のような方法を取ることができます。
- 静的なHTML Webページのみ(サーバーサイド・レンダリングなし)をCDNから直接配信、
- ページ上の画像を避ける
- CSSを最小化または削除する
- JavaScriptや外部依存ファイルが読み込まれないようにする
TBTのスコアをハックすることは(実際には)できない。
TBTは、FCP後にメインスレッドがJavaScriptタスクにブロックされ、ユーザー入力に対する応答が妨げられた時間の合計を測定します。良いTBTスコアは200ms以下です。
複雑な状態計算やDOM操作をページロード時に(レンダリングされたHTMLを送信する前にサーバーではなく)クライアントで行うJavaScriptを多用したWebアプリケーション(シングルページアプリケーションなど)は、TBTスコアが悪くなりがちです。
この場合、すべてのJavaScriptをLighthouseテストが終了するまで延期することで、TBTスコアをハックできる可能性があります。
とはいえ、FCPとLCPを満足させ、ある時点で何かが起こることをユーザーに知らせるために、何らかのプレースホルダーコンテンツやローディング画面を提供する必要があります。さらに、あなたが使っているフロントエンドフレームワークをハックするために、余計なことをしなければならないでしょう。
(ページのロードタイムラインのある時点で、任意の時間後に別のReactアプリをロードするようなプレースホルダーページをロードしたくないでしょう!)
興味深いのは、クライアントでJavaScriptを使っていろいろと派手なことをする一方で、最新のWebエコシステムの進歩が、TBTスコアがあまり良くない確率を減らすのに役立っているということです。
多くのフロントエンドフレームワークは、最新のホスティングプロバイダーと連携して、クライアントサイドのJavaScriptなしでページをレンダリングし、オンデマンドで複雑なロジックを処理することが可能です。
クライアントのJavaScriptをなくすことがゴールではありませんが、JavaScriptの使用量を大幅に減らすオプションがたくさんあることは確かで、ページロード時にメインスレッドで大量の計算を行うリスクを最小限に抑えることができます。
【結論】Lighthouse は大まかな目安に過ぎない!
Google Lighthouseは、特定のWebサイトの問題点をすべて検出できるわけではありません。
Lighthouseのパフォーマンススコアは、ユーザー入力への対応という観点からページのユーザビリティを優先していますが、2024年になってもまだ、ひどいユーザビリティやアクセシビリティの問題をすべて検出することはできないことが分かりました。
2019年、Manuel Matuzović氏は、Lighthouseがかなり素晴らしいと思っているひどいページを意図的に作成する実験を発表しました。
私は5年後、Lighthouseはもっと良くなっているかもしれないと予想しました。
この最終デモページでは、入力イベントがCSSとJavaScriptによって無効化され、ユーザーの入力に技術的に反応しないページになっています。
5秒後、JavaScriptがスイッチを切り、ボタンをクリックできるようになります。
このページでも、パフォーマンスとアクセシビリティの両方で100点を獲得しています。
ユーザビリティ・テストと常識の代用として、Lighthouseに頼ることはできません。
もっとくだらないハック
人生何事もそうですが、システムを利用する方法は必ずあります。ここでは、あなたのLighthouseのパフォーマンス・スコアを人為的に他を圧倒させる、試行錯誤を重ねた保証付きのハックをご紹介します。
- Lighthouseのテストは、最速かつ最高スペックのハードウェアでのみ実行してください。
- インターネット接続が最速であることを確認してください。
- フィールドデータは決して使用せず、前述の最速・最高スペックのハードウェアと超高速インターネット接続を使用して収集したラボデータのみを使用してください。
- 友人や同僚、インターネット上の不特定多数の人々に感動を与えたい結果が得られるまで、さまざまな条件やこの記事で説明した特別なコード・ハックを用いてラボでテストを再実行してください。
注:WebパフォーマンスとWebサイトの最適化方法について学ぶ最良の方法は、この記事で取り上げたことの真逆を常に行うことです。
そして最後に、パフォーマンスのスキルを本格的にレベルアップするには、Sentryのようなアプリケーション・モニタリング・ツールを使うことをオススメします。LighthouseをCanary版、Sentryを本番データを収集する、無駄のない、平均的な、Webバイタルマシンと考えてください。
そして最後に、教育目的のために、ここに完全なデモサイトへのリンクを掲載します。
ぜひご活用ください。