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 はヒューリスティックに基づいています。そのため、エラーが発生しやすいです。以下の 問題があります:
-
アルゴリズムは特定タイプのユーザー入力を検出すると停止します。しかし、これはユーザー入力が メインコンテンツ表示前に発生した場合、アルゴリズムがメインコンテンツを 捕捉できません。実際、ごく早くユーザー入力があると、アルゴリズムは無意味な結果や全く結果を 生成しない可能性もあります。
-
画像カルーセルを考慮するため、コンテンツが削除されてもなお最大のものとして 扱われます。これは、大きなコンテンツをプレースホルダーに使う スプラッシュスクリーンがあるウェブサイトでは問題となります。
LargestContentfulPaint API はドキュメントのロードに基づいています。したがって、以下のケースではリセットされません:
-
Back-forward cache(bfcache)からの復元。
-
JavaScript やリッチなアプリケーション内で使われる 同一ドキュメント履歴ナビゲーション。
LargestContentfulPaint API を利用する際、これらを 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。
-
largest contentful paint width という概念。初期値は 0。
-
largest contentful paint height という概念。初期値は 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、paint timing info paintTimingInfo、順序付き集合のpending image records paintedImages、および順序付き集合の要素
paintedTextNodes を受け取った場合、以下の手順を実行する:
注記: paintedImages 内の各 pending image record および paintedTextNodes 内のテキスト要素は、mark paint timing から、要素が描画可能(すなわち opacity・visibility がある)かつ contentful(画像リソースまたはブロックフォントが十分ロードされている)の最初の描画で、正確に一度だけ報告される。
-
window を、document の relevant global object とする。
-
window の has dispatched scroll event または has dispatched input event のいずれかが true なら、return する。
-
currentSize を document の largest contentful paint size とする。
-
currentWidth を document の largest contentful paint width とする。
-
currentHeight を document の largest contentful paint height とする。
-
largestSize を currentSize とする。
-
newCandidate を null とする。
-
各 record を paintedImages について:
-
imageElement を record の element とする。
-
imageElement が paint timing で公開されていない場合(document に対して)、continue。
-
intersectionRect を、imageElement を target、viewport を root として intersection rect アルゴリズムを使用して得られる値とする。
-
result を、imageElement、intersectionRect、および record のrequest を指定した effective visual size の結果とする。
-
result が null なら、continue。
-
result の size が largestSize 以下なら、continue。
-
largestSize に result の size をセットする。
-
-
newCandidate を新しい largest contentful paint candidate(以下の値をセット)にする:
-
各 textNode を paintedTextNodes について:
-
textNode が paint timing で公開されていない場合(document に対して)、continue。
-
textNode の alpha channel 値 <=0 または opacity 値 <=0 の場合:
-
textNode の text-shadow 値が none、 textNode の stroke-color 値が transparent かつ textNode の stroke-image 値が none なら、continue。
-
-
intersectionRect を、すべての
Textノードの textNode の 所有テキストノードの集合 の border box の和集合と、visual viewport との共通部分とする。 -
result を、textNode、intersectionRect、および null を与えた effective visual size の結果とする。
-
result が null なら、continue。
-
result の size が largestSize 以下なら、continue。
-
largestSize に result の size をセットする。
-
newCandidate を新しい largest contentful paint candidate(以下の値でセット)にする:
-
-
newCandidate が null でなければ:
-
currentSize が 0 より大きい場合:
-
LargestContentfulPaint エントリを作成し、newCandidate、paintTimingInfo、document を用いる。
-
4.3. 要素の実効視覚サイズの判定
要素の効果的視覚サイズを決定するには、次の手順を実行します:
- 入力
-
intersectionRect、
DOMRectReadOnlyimageRequest、
Requestまたは nullelement、要素
document、Document
- 出力
-
effective visual size result、これはstructであり、要素として size(数値)、width(数値)、および height(数値)を持ち、Largest Contentful Paint に報告する有効な見た目のサイズ・幅・高さ(ピクセル単位)を表す。要素がLCP候補であってはならない場合は null。
-
width を intersectionRect の
width(最大整数に切り上げ)とする。 -
height を intersectionRect の
height(最大整数に切り上げ)とする。 -
size を
widthとする。* height -
root を document の browsing context の top-level browsing context の active document とする。
-
rootWidth を root の visual viewport の幅(スクロールバーを除く)とする。
-
rootHeight を root の visual viewport の高さ(スクロールバーを除く)とする。
-
size が rootWidth × rootHeight に等しい場合、null を返す。
-
imageRequest が null でなければ、画像の位置と拡大率を調整するために次を実行:
-
imageRequest の response のバイト数が size * 0.004 より小さい場合は null を返す。
注記: このヒューリスティックは画像リソースがユーザーにとって十分コンテンツフルかどうかを判定する。転送されたファイルサイズと実際に生成されるピクセル数(デコードやスケーリング後)を比較する。ごく少量のバイトで大量のピクセルをエンコードしている画像は通常、低コンテンツな背景やグラデーションなどであり、LCP候補としない。
-
concreteDimensions を imageRequest の concrete object size(element の中)とする。
-
visibleDimensions を concreteDimensions とし、位置は object-position や background-position、element の content box で調整する。
注記: これらのアルゴリズムの一部はCSSで厳密には定義されていない。期待される結果は element 内の画像の実際の位置とサイズを
DOMRectReadOnlyで得ることである。 -
clientContentRect を visibleDimensions(element の transform を適用したもの)を含む最小の
DOMRectReadOnlyとする。 -
intersectingClientContentRect を clientContentRect と intersectionRect の共通部分とする。
-
width を intersectingClientContentRect の
width(最大整数に切り上げ)とする。 -
height を intersectingClientContentRect の
height(最大整数に切り上げ)とする。 -
size を
widthにセットする。* height注記: これによって要素の装飾ではなく、画像自身とのみ交差することを保証する。
-
naturalArea を
imageRequest の natural widthとする。* imageRequest の natural height -
naturalArea が 0 なら null を返す。
-
boundingClientArea を
clientContentRect のとする。width* clientContentRect のheight -
scaleFactor を
boundingClientAreaとする。/ naturalArea -
scaleFactor が 1 より大きい場合、size を scaleFactor で除算する。
-
-
effective visual size result を返す。size は size、width は width、 height は height とする。
-
4.4. LargestContentfulPaint エントリーを作成する
LargestContentfulPaint
エントリーを作成するには、ユーザーエージェントは次の手順を実行する:
- 入力
-
candidate、largest contentful paint candidate
paintTimingInfo、paint timing info
document、
Document - 出力
-
なし
-
document の largest contentful paint size を、 candidate の size で設定する。
-
document の largest contentful paint width を candidate の width で設定する。
-
document の largest contentful paint height を candidate の height で設定する。
-
url を空文字列とする。
-
もし candidate の request が null でなければ、 url を candidate の request の request URL で設定する。
-
entry を新しい
LargestContentfulPaintエントリ(document の relevant realm で、paint timing info が paintTimingInfo)にし、下記の値を設定する: -
PerformanceEntry をキューする entry。
-
5. セキュリティとプライバシーに関する考慮事項
このAPIは低レベルのプリミティブとしてPaint Timingに依存しています。同様のElement Timing APIと異なり、LCPはたとえ小さい要素であっても、ページ読み込み時点までで最大であればタイミング詳細を開示する可能性があります。しかし、これはElement Timingが既に可能にしている範囲を超えた機微な情報は公開しないと思われます。