First Contentful Paint (FCP)
FCP とは? #
First Contentful Paint (FCP) 指標は、ページの読み込みが開始されてからページ内のコンテンツのいずれかの部分が画面上にレンダリングされるまでの時間を測定します。この指標における "コンテンツ" は、テキスト、画像 (背景画像を含む)、<svg>
要素、白以外の <canvas>
要素のことを指しています。
上の読み込みタイムラインでは、FCP は 2 フレーム目で発生しています。これが、最初のテキストや画像要素が画面にレンダリングされるタイミングです。
コンテンツの一部がレンダリングされたものの、すべてのコンテンツがレンダリングされたわけではないことがわかります。これは、First Contentful Paint (FCP) と、ページのメイン コンテンツの読み込み完了タイミングの測定が目的となる Largest Contentful Paint (LCP) の重要な違いです。
FCP における良いスコアとは? #
良好なユーザー体験を提供するために、サイトは First Contentful Paint が 1.8 秒以下になるように努力する必要があります。ほぼすべてのユーザーに対してこの目標値を確実に達成するためには、モバイル デバイスとデスクトップ デバイスに分けた上で、総ページロード数の 75 パーセンタイルをしきい値として設定します。
FCP の測定方法 #
FCP はラボ環境または実際のユーザー環境で測定が可能で、以下のツールが使用できます。
フィールド測定を実施するためのツール #
- PageSpeed Insights
- Chrome User Experience Report
- Search Console (Core Web Vitals Report)
web-vitals
JavaScript ライブラリ
ラボ測定を実施するためのツール #
JavaScript を使用して FCP を測定する #
- Chrome 60, Supported 60
- Firefox 84, Supported 84
- Edge 79, Supported 79
- Safari 14.1, Supported 14.1
JavaScript を使用した FCP の測定には、Paint Timing API を使用することができます。以下の例では、first-contentful-paint
という名前の paint
エントリをリッスンし、コンソールにログを記録する PerformanceObserver
の作成方法を示しています。
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
console.log('FCP candidate:', entry.startTime, entry);
}
}).observe({type: 'paint', buffered: true});
上記の例では、ログに記録されている first-contentful-paint
エントリが、最初の視覚コンテンツ要素が描画されるタイミングを教えてくれます。ただし、このエントリが FCP の測定に有効とはならない場合もあります。
次のセクションでは、API がレポートする内容と、指標の計算方法の違いについて説明します。
指標と API の違い #
- API はバックグラウンド タブで読み込まれているページに対しても
first-contentful-paint
エントリをディスパッチしますが、FCP を計算する場合には、そういったページは無視する必要があります (最初の描画タイミングが考慮されるのは、ページがずっとフォアグラウンドにあった場合のみです)。 - API は、ページが Back/Forward Cache から復元された場合の
first-contentful-paint
エントリはレポートしませんが、これらはユーザーにとっては別々のページ訪問となるため、こういったケースにおいても FCP は測定される必要があります。 - API では クロス オリジンの iframe の描画タイミングはレポートされない場合がありますが、FCP を正確に測定するためにはすべてのフレームを考慮に入れる必要があります。サブフレームが集約のために API を使用してその親フレームに描画タイミングをレポートすることができます。
こういった微妙な違いをすべて記憶していなくても、web-vitals
JavaScript ライブラリを使用して FCP を測定すれば、これらの違いを (可能な限り) 処理してくれます。
import {onFCP} from 'web-vitals';
// 実行可能となった時点ですぐに FCP の測定やログ記録を実行します。
onFCP(console.log);
JavaScript を使用して FCP を測定する方法に関する詳細な例については、onFCP()
のソース コードを参照してください。
FCP の改善方法 #
特定のサイトについて FCP の改善方法を把握するには、Lighthouse でパフォーマンス監査を実行し、そこで推奨される具体的な Opportunities (改善機会) や Diagnostics (診断) に注目します。
FCP の (あらゆるサイトに共通する) 一般的な改善方法については、以下のパフォーマンス ガイドを参照してください。
- レンダリングをブロックするリソースを排除する
- CSS を圧縮する
- 使用されていない CSS を削除する
- 必要なオリジンに事前接続する
- サーバーの応答時間 (TTFB) を短縮する
- 複数のページ リダイレクトを避ける
- キー リクエストを事前に読み込む
- 過大なネットワーク ペイロードを回避する
- 効率的なキャッシュ ポリシーを使用して静的なアセットを配信する
- 過大な DOM サイズを回避する
- クリティカルなリクエストの深さを最小化する
- Web フォントの読み込み中にテキストが表示されたままになっていることを確認する
- リクエスト数を少なく、転送サイズを小さく維持する
CHANGELOG #
Occasionally, bugs are discovered in the APIs used to measure metrics, and sometimes in the definitions of the metrics themselves. As a result, changes must sometimes be made, and these changes can show up as improvements or regressions in your internal reports and dashboards.
To help you manage this, all changes to either the implementation or definition of these metrics will be surfaced in this CHANGELOG.
If you have feedback for these metrics, you can provide it in the web-vitals-feedback Google group.