1. 導入
このセクションは規範的ではありません。 LargestContentfulPaint APIは、開発者がウェブページの読み込みおよび描画プロセスを可視化し、最適化できるようにします。
開発者は、ユーザーの視覚的レンダリング体験と相関する信頼性ある指標を必要としています。First PaintやFirst Contentful Paintのような描画指標は初期のレンダリングに焦点を当てていますが、描画されたコンテンツの重要性を考慮していないため、ユーザーがまだそのページを有用だと感じていない時点を示す場合もあります。
Largest Contentful Paint(LCP)は以下のようなページ読み込み指標を目指します:
-
First PaintやFirst Contentful Paintよりユーザー体験とより強く相関する
-
理解・説明しやすい
-
恣意的操作(ゲーム化)の余地を減らす
ページ読み込み中の最大のペイントは、ユーザー視点から意味のあるイベントを示す可能性が高いため、デフォルトで開発者に公開し、パフォーマンスチームや分析プロバイダ、ラボベースの計測ツールが、コンテンツ制作者自身による追加注釈なしで指標を取得できるようにします。
このAPIは[PAINT-TIMING]で定義された概念に大きく依存しており、これはこの高レベル機能が基盤としている低レベルのプリミティブと見なすことができます。もしコンテンツ制作者が重要な点を注釈付けしたい場合は、[ELEMENT-TIMING] APIを使うことで、報告対象の要素をより柔軟に制御できます。
注意: Largest Contentful Paint APIは、タイミング適格な要素だけを公開します。Element Timingと異なり、Largest Contentful Paintのために要素へ注釈を追加する必要はありません。
1.1. 最大コンテンツ
このAPIで用いられるアルゴリズムは、これまで見つかったコンテンツを追跡します。新しい最大のコンテンツが見つかるたびに新しいエントリーが作成されます。削除されたコンテンツもアルゴリズムで考慮されます。特に、削除されたコンテンツが最大だった場合は、より大きなコンテンツが追加されたときにのみ新たなエントリーが作成されます。スクロールやインプットイベントが発生すると、その後サイトに新たなコンテンツが導入される可能性が高いため、アルゴリズムは終了します。
1.2. 使用例
次の例は画像と大量のテキストを表示します。その後、開発者がページ読み込み中に最大ペイントの候補エントリーを受け取るオブザーバーを登録します。
< img src = "large_image.jpg" > < p id = 'large-paragraph' > This is large body of text.</ p > ...< script > const observer= new PerformanceObserver(( list) => { let perfEntries= list. getEntries(); let lastEntry= perfEntries[ perfEntries. length- 1 ]; // Process the latest candidate for largest contentful paint }); observer. observe({ entryTypes: [ 'largest-contentful-paint' ]}); </ script >
1.3. 制限事項
LargestContentfulPaint APIはヒューリスティックに基づきます。そのため誤りが発生しやすい性質があります。主な問題点:
-
アルゴリズムは特定のユーザー入力を検出すると停止します。しかし、これはメインコンテンツが表示される前にユーザー入力が行われると、メインコンテンツを捕捉できないことを意味します。実際、ユーザー入力が非常に早いと、意味のない結果や結果が得られない場合があります。
-
画像カルーセルに対応するため、コンテンツが削除されても引き続き「最大」として扱われます。これは大きなコンテンツをプレースホルダーに使うスプラッシュ画面などで問題を引き起こします。
2. 用語
最大 コンテンツ描画候補は、以下のメンバーを含む構造体です:
3. 最大コンテンツの表示
最大コンテンツの表示には以下の新しいインターフェイスが関わります:
3.1. LargestContentfulPaint
インターフェース
[Exposed =Window ]interface :LargestContentfulPaint PerformanceEntry {readonly attribute DOMHighResTimeStamp ;loadTime readonly attribute DOMHighResTimeStamp ;renderTime readonly attribute unsigned long ;size readonly attribute DOMString ;id readonly attribute DOMString ;url readonly attribute Element ?; [element Default ]object (); };toJSON LargestContentfulPaint includes PaintTimingMixin ;
各LargestContentfulPaint
オブジェクトには、以下の関連する概念があります:
-
size(サイズ)、初期値は0。
-
loadTime(ロード時刻)、初期値は0。
-
id(ID)、初期値は空文字列。
-
url(URL)、初期値は空文字列。
-
関連付けられた
Elementを含む element(要素)、初期値は。null
entryType
属性のgetterは、DOMString
の を返さなければならない。
name
属性のgetterは空文字列を返さなければならない。
startTime
属性のgetterは、this の
renderTime
の値を返さなければならない。
duration
属性のgetterは 0 を返さなければならない。
renderTime
属性は、デフォルトペイントタイムスタンプを、this の ペイントタイミング情報
で指定して返さなければならない。
loadTime
属性は、this の loadTime の値を返さなければならない。
size
属性は、this の size の値を返さなければならない。
id
属性は、this の id
の値を返さなければならない。
url
属性は、this の url
の値を返さなければならない。
element
属性のgetterは次の手順を実行しなければならない:
-
this の element が paint timing用に公開されていない(引数null)場合、null を返す。
注記: 上記のアルゴリズムは、Document
の子孫でなくなった要素は
element
属性getterによって返されなくなり、シャドウDOM内の要素も含まれることを意味します。
この仕様はさらに、Document
にlargest
contentful paint size(最大コンテンツペイントサイズ)概念を追加し、初期値は0とします。
4. 処理モデル
各Window
はスクロールイベントがディスパッチされたかというブール値を持ち、初期値はfalseです。
4.1. DOM仕様への修正
このセクションは[DOM]仕様が修正され次第、削除予定です。
ステップ1の直後に次のステップを追加:
-
targetのrelevant global objectが
Windowオブジェクトであり、eventのtypeがscrollであり、かつそのisTrustedがtrueであれば、targetのrelevant global objectのスクロールイベントがディスパッチされたかをtrueにする。
4.2. 最大コンテンツの表示を報告する
Document
document、描画タイミング情報 paintTimingInfo、順序付け集合である
保留中画像レコード paintedImages、および
順序付け集合である
要素 paintedTextNodesを受け取り、次の手順を実行する:
注記: paintedImagesに含まれる各保留中画像レコードと paintedTextNodesのテキスト要素は、それぞれ一度だけ報告されます(描画タイミングのマークから)。要素が描画可能(例:不透明・可視)かつコンテンツが表示可能(画像リソースやブロックしているフォントが十分に読み込まれている)となった最初の描画でのみ対象となります。
-
windowをdocumentの関連グローバルオブジェクトとする。
-
もしwindowのスクロールイベントが dispatch 済みまたは入力イベントが dispatch 済みのいずれかが true なら、終了する。
-
newCandidateSizeをdocumentの最大コンテンツ描画サイズとする。
-
newCandidateをnullにする。
-
paintedImagesの各 recordについて:
-
imageElementをrecordの要素とする。
-
もしimageElementが描画タイミング用に公開済みでない場合(documentを指定)、次へ。
-
intersectionRectを、intersection rect algorithm により imageElementをターゲット、viewportをルートとして返される値とする。
-
もしsizeがnewCandidateSize以下なら次へ。
-
newCandidateSizeをsizeに設定する。
-
newCandidateに新しい最大コンテンツ描画候補を設定し、その 要素をimageElement, サイズをsize, リクエストを recordのリクエスト, ロード時間を recordのロード時間に設定する。
-
-
paintedTextNodesの各 textNodeについて:
-
もしtextNodeが描画タイミング用に公開済みでない場合(documentを指定)、次へ。
-
もしtextNodeのアルファチャンネル値が0以下または 不透明度 値が0以下の場合:
-
もしtextNodeのtext-shadow値がnoneかつ textNodeのstroke-color値が transparent、 textNodeのstroke-image値が none なら次へ。
-
-
intersectionRectを、textNodeの所有テキストノード集合内の全ての
Textノードの border box の合計を ビジュアルビューポートと重ね合わせたものとする。 -
sizeをintersectionRectとnullを用いた 効果的視覚サイズによって算出する。
-
もしsizeがnewCandidateSize以下なら次へ。
-
newCandidateSizeをsizeに設定する。
-
newCandidateに新しい最大コンテンツ描画候補を設定し、その 要素をtextNode, サイズをsize, リクエストをnull、 ロード時間を0に設定する。
-
-
もしnewCandidateがnullでなければ:
-
LargestContentfulPaintエントリーを作成する (newCandidate, paintTimingInfo, documentを指定)。
-
4.3. 要素の実効視覚サイズの判定
要素の効果的視覚サイズを決定するには、次の手順を実行します:
- 入力
-
intersectionRect、
DOMRectReadOnlyimageRequest、
Requestまたは nullelement、要素
document、文書
- 出力
-
Largest Contentful Paint に報告するサイズ(ピクセル単位)、または要素がLCP候補でなければnull。
-
width を intersectionRect の
横幅とする。 -
height を intersectionRect の
縦幅とする。 -
size を
widthとする。* height -
root を document の 閲覧コンテキスト の トップレベル閲覧コンテキスト の アクティブ文書とする。
-
rootWidth を root の 視覚ビューポートの横幅(スクロールバーを除く)とする。
-
rootHeight を root の 視覚ビューポートの高さ(スクロールバーを除く)とする。
-
もし size が rootWidth × rootHeight に等しいなら、null を返す。
-
imageRequest が null でない場合、画像の位置や拡大調整のため次の手順を実行:
-
imageRequest の レスポンスのバイト長が size * 0.004 より小さいなら、null を返す。
注記: このヒューリスティックはユーザにとって十分コンテンツとなる画像データ量か判定する。転送されたファイルサイズ(バイト数)と実際生成されるピクセル数を比較する。非常に少ないバイト数で大量のピクセルをエンコードしている画像は、低コンテンツ背景やグラデーション等であり、LCP候補と見なされません。
-
concreteDimensions を imageRequest の 具体オブジェクトサイズ(element内)とする。
-
visibleDimensions を concreteDimensionsの位置調整結果とし、object-position または background-position、elementのコンテンツボックスを使って調整。
注記: これらのアルゴリズムはいくつかはCSSで厳密には定義されていません。期待される結果は、element内画像の実際位置とサイズを
DOMRectReadOnlyで得ることです。-
clientContentRect を visibleDimensions を含む最小の
DOMRectReadOnly(elementのtransformを適用)とする。 -
intersectingClientContentRect を clientContentRect と intersectionRect の重なり部分とする。
-
size を
intersectingClientContentRectのとする。横幅* intersectingClientContentRectの高さ
注記: 画像本体のみと要素装飾部を区別し画像本体部分のみ重なりを取っています。
-
-
size を返す。
-
4.4. LargestContentfulPaint エントリーを作成する
LargestContentfulPaint
エントリーを作成するには、ユーザーエージェントは次の手順を実行する:
- 入力
-
candidate、最大コンテンツ描画候補
paintTimingInfo、描画タイミング情報
document、
Document - 出力
-
なし
-
document の 最大コンテンツ描画サイズを candidate の サイズに設定する。
-
url を空文字列とする。
-
candidate の リクエスト が null でなければ、 url を candidate の リクエスト の リクエストURLとする。
-
entry を新しい
LargestContentfulPaintエントリー(document の 関連レルムで、描画タイミング情報は paintTimingInfo)とし、 -
PerformanceEntry entry をキューする。
-
5. セキュリティとプライバシーに関する考慮事項
このAPIは低レベルのプリミティブとしてPaint Timingに依存しています。同様のElement Timing APIと異なり、LCPはたとえ小さい要素であっても、ページ読み込み時点までで最大であればタイミング詳細を開示する可能性があります。しかし、これはElement Timingが既に可能にしている範囲を超えた機微な情報は公開しないと思われます。