2023年11月27日
First Important Paint−カスタム指標の開発
(2023-06-10)by Kevin Farrugia
本記事は、原著者の許諾のもとに翻訳・掲載しております。
2020年5月、GoogleがWebサイトのパフォーマンス測定を目的としたユーザー中心の指標を発表しました。コアウェブバイタル(CWV)と呼ばれるこの一連の指標には、以下が含まれます。
- LCP (Largest Contentful Paint):ビューポート内で最大の要素が表示されるまでの時間。
- FID (First Input Delay):ユーザーの最初の入力に応答するまでの遅延時間。近々INP (Interaction to Next Paint)に置き換わる予定。
- CLS (Cumulative Layout Shift):ページのコンテンツがどれだけ移動したかを表す指標。-
CWVの狙いは、世の中にあふれるさまざまなパフォーマンス指標を簡素化し、最も重要な指標に優先的に取り組めるようにすることです。この取り組みは好影響をもたらしています。CWVの発表以降、多くのWebオーナーやサービスプロバイダがWebサイトのパフォーマンスに力を注いでおり、Web全体でユーザー体験が向上しています。
cwvtech.reportから引用した上のグラフが示すように、CWVのしきい値を満たすWebサイトの割合が22%から40%に増えています。
カスタム指標の役割
ブラウザにあらかじめ用意されているデフォルト指標に独自のカスタム指標を追加することで、Webサイトのユーザー体験をより正確に測定できる場合があります。例えば、LCPは最も大きな要素が最も重要であると想定します。その通りの場合もありますが、そうではない場合もあります。
上の画像群では、赤枠で囲まれたフレームの、青のグラデーションの背景画像がLCP要素です。一方、最も重要な要素は、その次のフレームでレンダリングされる「Lorem」というページタイトルでしょう。これは極端な例かもしれませんが、重要な要素がグリッドまたはテーブルの場合や、背景がposter
画像を含む<video>
要素の場合にも同じ問題が生じます。
Element Timing API
LCPと同様に、Element Timing APIを使用することで、ページ上でDOM要素がレンダリングされるタイミングを測定することができます。しかし、LCPと異なるのは、測定する要素を開発者が選べることです。Element Timing API は、elementtiming
属性を要素に追加することで設定できます。
Element Timing API の最大の制約は、Chromiumベースのブラウザしか対応していないことです。また、一部の要素しか対応していません。
User Timing API
User Timing APIを使用することで、特定のタイミングにマークや指標を設定することができます。例えば、ページ上に要素が描画されたタイミングや、重要なタスクが実行されたタイミングなどに設定できます。
// タスク開始時の時間を記録する
performance.mark('doSomething:start');
await doSomething();
// タスク終了時の時間を記録する
performance.mark('doSomething:end');
// :startと:endの時間差を測定する
performance.measure('doSomething', 'doSomething:start', 'doSomething:end');
実ユーザー指標とラボテスト
カスタム指標を開発するに当たって最初に問うべきことは、この指標を実際のユーザーとデバイスで測定したいのか、それともラボテスト(※)でのみ測定したいのかということです。どちらの指標も有益ですが、それぞれに異なる利点があります。 (※訳注:ユーザーではなく、開発者がツール等を使って行うテストをラボテストと呼称しています) 実ユーザー指標(Real user metrics, RUM)は、ユーザー体験を全面的に測定することができます。単一のスコアではなく、異なるユーザーや体験を反映したさまざまな値が得られます。例えば、90パーセンタイルのユーザーは散々な体験をするかもしれませんが、平均的なユーザーは良い体験をします。指標に影響を及ぼすさまざまな要因(地理的な場所、ブラウザ、デバイス)を理解することで、自分のユーザーのためにWebサイトを最適化することができます。マイナス面としては、RUMソリューションの実装は複雑で、費用がかさむ場合があることです。
上のスクリーンショットはSpeedCurveから引用したもので、異なるユーザー体験の分布を示しています。
ラボテストは管理された環境で行われます。接続速度、デバイス、テストを実行する場所などいくつかのパラメータは設定できるかもしれません。テスト結果のレポートには、ページ上で測定したさまざまな指標について詳しく記載されます。
ラボテストはデバッグに極めて有効です。一定の間隔でラボテストを行うことにより、長期間にわたってページのパフォーマンスを比較し、不具合を特定することができます。筆者がラボテストを行う際には、WebPageTestというツールを愛用しています。
優れた指標の特徴
ポール・アイリッシュが2020年にLCPについて紹介した際、優れた指標が持つべき8つの特徴について説明しました。これを少しアレンジしたものが、Chromiumのソースコードに関するドキュメントの中にもあります。
- 代表性:ユーザー体験および事業価値と相関する。
- 解釈可能性:指標およびその価値が理解しやすい。
- 正確性:測定すべき内容を正確に測定できているか。
- 単純性:計算方法が複雑でない。
- 直交性:測定する内容が他の指標と重複しない。
- 安定性:測定にばらつきが少ない。
- 弾力性:入力に小さな変化があると、指標にも小さな変化が表れる。
- 相関性:他の指標との相関性や、ラボテストとフィールドテストの間の相関性がある。
観察者効果
優れた指標の重要な特徴としてもう一つ挙げられるのが、テストそのものに影響を及ぼさないということです。科学用語では、観察する行為がテストに影響を与えることを観察者効果と呼びます。カスタム指標の測定によりページの表示速度が明らかに低下する場合、それは良い指標とは言えません。
FIP (First Important Paint)
First Important Paintは、最初の注釈付きHTML要素がページ上に表示されるまでの時間を測定するために開発されたカスタム指標です。
この指標が必要になったのは、LCP要素がユーザー体験と一致しない場合があったためです。さらに、ページを構成するさまざまなコンポーネントが、異なるチームの開発者によって作成されることも多くありました。ページではなく要素に注釈を付けることで、自動的にFIP候補として扱われるため、開発者はコンポーネントがどのページで使用されるのか知る必要がありません。
(それに、3文字の略称も付いているため正規のものに見えますよね😛)
FIPは優れた指標か?
First Important Paintは、ユーザーが実際に使う環境でのテストでもラボテストでも測定できます。FIPが優れた指標かどうかを判断するため、マーケットの異なる2つの本番サイトでいくつかのラボテストを実施し、データを収集しました。
代表性
FIPの代表性を検証するため、異なるページのスクリーンショットと異なるデバイスを使用したラボテストをいくつか用意し、この指標について何も知らない同僚数名に最も重要な要素が描画されていると思うフレームを選んでもらいました。このデータをもとに、重要な要素として扱うべきコンポーネントを判断し、LCPがすでにこの情報を示していたかどうかを評価しました。
解釈可能性
FIPは分かりやすく、ミリ秒単位で測定されます。
正確性
カスタム指標の正確性を測定するため、FIP要素がLCP要素でもあるラボテストをいくつか実施しました。これはつまり、FIPとLCPの値が同等であることが望ましいということです。テキスト要素には、LCPの代わりにElement Timing APIを使用しました。
テストは画像要素とテキスト要素を対象とし、接続速度の異なる3つの回線を使用して行いました。ネイティブ回線では、FIPとLCPの差は50ミリ秒でした。Regular 4G回線とRegular 3G回線では、それぞれ200ミリ秒と1000ミリ秒に差が広がりました。
これらの結果は期待外れに見えるかもしれませんが、測定結果は一貫しており、LCPまたはElement Timing API とFIPの差はテストによって大きく違いませんでした。例えば、あるテストではLCPよりFIPの方が50ミリ秒速く、次のテストでは50ミリ秒遅かった方が問題です。
正確性に欠ける理由はさまざまであり、指標の計算方法の限界でもあります。
単純性
FIPを測定、計算するためのコードは単純で、デバッグや変更も必要に応じて簡単に行えます。
直交性
FIPは、ページ上で最も重要な要素を測定するためのカスタム指標です。最も重要な要素が最も大きな要素でもある場合があり、その場合はFIPとLCPが重複することになります。
安定性
FIPの安定性を測定するため、接続速度の異なる3つの回線でラボテストを行いました。
上のグラフが示すように、どの回線でもテストによるばらつきはほとんどありませんでした。
弾力性
ユーザー体験の変化に比例した変化が指標に見られる場合、その指標は弾力性があるとみなされます。FIPに弾力性があるかどうかをテストするため、基準となるデモページと、これに変更を加え、フォントファイルをセルフホストしてあらかじめ読み込むようにしたページを作成しました。タイトルのレンダリングが早くなるため、ユーザー体験が改善されることが期待され、それに伴いFIPも改善するはずです。
FIPの古いバージョンの中に、この変更による改善が一切見られないものがありました。そのおかげで、指標に不備があったことが判明しました。FIPはテキスト要素がDOMに追加された時間を記録していたのですが、Webフォントがまだダウンロードされていないケースを考慮していなかったのです。
この問題を解決してからは、ユーザー体験の向上に比例した小さな改善がFIPに見られるようになりました。
上の比較をご覧ください。元ページのテストでは、LCPが1.315秒で、FIPが1.470秒でした。上記の修正を加えた最適化ページのテストでは、LCPが1.305秒で、FIPは1.188秒に改善されました。この改善はユーザー体験とも一致しており、2回目のテストではユーザー体験が大幅に改善されています。
相関性
FIPと他の指標の相関性を確認するため、正確性の説明で述べたのと同じテストを使用しました。散布図にFIPとLCPの測定結果を記入し、決定係数を計算しました。2つの指標が相関するためには、両者の値が一致する必要はありませんが、LCPが増えたらそれに比例してFIPも増え、FIPが増えたら同様にLCPも増える必要があります。
テキスト要素の場合、Regular 4G回線で強い相関が見られたものの、Regular 3G回線では同等の強い相関が見られませんでした。
SpeedCurveで入手可能な実ユーザーデータを使用し、FIPとビジネス指標の相関性を見ることもできます。
上のグラフはSpeedCurveから引用したものですが、FIPが増えるとページの直帰率(青い線)も増えており、両者の間には正の相関関係が見られます。
観察者効果
最後に、この指標はテスト対象のページのパフォーマンスに影響を及ぼさないことを確認したいと思います。指標を含むページと、指標の代わりに同等のサイズのレンダーブロッキングとなるスクリプトを含むページで同じテストを実施しました。
上のグラフが示すように、LCP要素は両者のテスト間でほとんど変わりませんでした。将来的には、LCPの他にJavaScriptのロングタスクも含めたテストを行ってみたいと思います。
まとめ
この記事の狙いは、社内で指標のレビューを行うきっかけになることです。CWVの対象範囲と優れたカスタム指標の条件を理解することで、自分が使用している指標を評価し、改善することができます。
First Important Paintは優れた指標でしょうか?限界もありますし、有用性もケースバイケースでしょう。しかし、我々にとっては現時点で重要な役割を果たしています。さらに改善を加え、ユーザー体験の他の側面を測定する新たなカスタム指標を追加していきたいと思っています。
最後までお読みいただきありがとうございました。ご意見やご質問のある方はぜひご連絡ください。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa