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. 用語
largest contentful paint candidateは、以下のメンバーを含む構造体です:
largest contentful paint candidate candidateは、以下の条件を満たす場合にlargest contentful paintの対象です:
-
candidateのelementの不透明度が0より大きい
-
candidateのelementがテキストノードである、あるいは candidateのrequestの responseのコンテンツ長(バイト数)が candidateのelementの実効視覚サイズ×0.004 以上であること
備考: このヒューリスティックは、画像リソースがユーザーにとって「内容のある」ものとして見えるだけのデータ量を含むかどうかを判定します。転送ファイルサイズとデコードや画像スケーリング後に実際に生成されるピクセル数とを比較します。ごく少数のバイトで極端に多くのピクセルをエンコードする画像は、一般的に内容の少ない背景やグラデーションなどであり、largest contentful paint候補として扱いません。
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、初期値は空文字列。
-
url、初期値は空文字列。
-
element:関連付けられた
Elementを含み、初期値は。null
entryType
属性のgetterはDOMString
を返さなければなりません。
name
属性のgetterは空文字列を返さなければなりません。
startTime
属性のgetterは、thisのrenderTime
の値が0でなければその値を、0の場合はloadTimeの値を返します。
duration
属性のgetterは0を返さなければなりません。
renderTime
属性は default paint timestamp (引数にthisのpaint timing
infoを与える)を返す。
loadTime
属性はthisのloadTimeの値を返します。
element
属性のgetterは次の手順を実行します:
-
thisのelementがpaint timing用に公開されていない場合、nullを返す。
備考: 上記のアルゴリズムは、documentの子孫でなくなった要素は、element属性のgetterで返されなくなることを意味します。shadow
DOM内の要素も含みます。
また、本仕様はDocument
を拡張しlargest
contentful paint sizeという概念(初期値0)を加えます。
さらに関連付けられたcontent
set(初期状態は空の集合)も加えます。content setは(Elementと
Requestの)タプルで埋められます。アルゴリズムがそれぞれのコンテンツを一度しか評価しないことを可能にし、パフォーマンス向上のために使われます。
備考: user agentはcontent
setを管理し、削除されたコンテンツがメモリリークを引き起こさないようにする必要があります。特に、タプルの寿命をElementsへの弱参照に紐付け、Elementsが削除された後にクリーニングできるようにします。集合はweb開発者に公開されないため、ガベージコレクションのタイミングが公開されることはありません。
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 の各 record について:
-
imageElement を record のelementとする。
-
imageElement が paint timing用に公開されていなければ、documentを与えて続行。
-
requestをrecordのrequestとする。
-
candidateを (imageElement, request) とする
-
intersectionRect を intersection rectアルゴリズムの結果(targetにimageElement、rootはviewport)とする。
-
Potentially add a LargestContentfulPaint entryにcandidate、 intersectionRect、paintTimingInfo、recordのloadTime、documentを渡す。
-
-
paintedTextNodes の各 textNode について、
-
もし textNode が paint timing 用に公開されていなければ、documentを与えて続行。
-
もし textNode の アルファチャンネル の値が0以下、または 不透明度 の値が0以下の場合:
-
もし textNode の text-shadow の値が none、 textNode の stroke-color の値が 透明 かつ textNode の stroke-image の値が none なら、続行。
-
-
candidate を (textNode, null) とする
-
intersectionRect を空の矩形とする。
-
各
Textノード text を textNode の 所有テキストノードの集合から取り出して:-
intersectionRect を text のボーダーボックスと intersectionRect をともに含む最小の矩形に拡張する。
-
-
intersectionRect をビジュアルビューポートと交差させる。
-
LargestContentfulPaint エントリーの追加検討を candidate、intersectionRect、paintTimingInfo、0、document で実行する。
-
4.3. 要素の実効視覚サイズの判定
実効視覚サイズを要素に対して判定するには、次の手順を実行する:
- 入力
-
intersectionRect、
DOMRectReadOnlyimageRequest、
Requestelement、要素
document、Document
- 出力
-
Largest Contentful Paintとして報告するサイズ(ピクセル単位)。要素がLCPの候補でない場合はnull。
-
widthをintersectionRectの
widthとする。 -
heightをintersectionRectの
heightとする。 -
sizeを
widthとする。* height -
rootをdocumentの閲覧コンテキストの最上位閲覧コンテキストのアクティブドキュメントとする。
-
rootWidthをrootのvisual viewportの横幅(スクロールバーを除く)とする。
-
rootHeightをrootのvisual viewportの縦幅(スクロールバーを除く)とする。
-
sizeがrootWidth×rootHeightと等しければ、nullを返す。
-
imageRequestがlargest contentful paintの候補として適格でなければnullを返す。
-
imageRequestがnullでない場合は、画像の位置やアップスケーリングに対応するため次を実行:
-
concreteDimensionsを、imageRequestのconcrete object size(element内)とする。
-
visibleDimensions を concreteDimensions に、 object-position または background-position および element の content box による位置調整を加えたものとする。
備考: これらのアルゴリズムの一部はCSSで厳密には定義されていません。期待される結果は、element内の画像の実際の位置とサイズを
DOMRectReadOnlyとして得ることです。-
clientContentRectを
DOMRectReadOnlyのうち、 visibleDimensionsにelementのtransformを適用した最小矩形とする。 -
intersectingClientContentRectをclientContentRectとintersectionRectの交差部分とする。
-
sizeを
intersectingClientContentRectのとする。width* intersectingClientContentRectのheight
備考: これは要素の装飾部分ではなく画像そのものとの交差だけを考慮するためです。
-
naturalAreaを
imageRequestのnatural widthとする。* imageRequestのnatural height -
naturalAreaが0の場合はnullを返す。
-
boundingClientAreaを
clientContentRectのとする。width* clientContentRectのheight -
scaleFactorを
boundingClientAreaとする。/ naturalArea -
scaleFactorが1より大きければ、sizeをscaleFactorで割る。
-
-
sizeを返す。
-
4.4. LargestContentfulPaintエントリーの追加検討
備考: Largest Contentful Paint APIを実装するユーザーエージェントは、を
supportedEntryTypes
にWindowコンテキストで含める必要がある。
これにより開発者はAPIサポートを検出できる。
LargestContentfulPaint
エントリーの追加検討を行うには、ユーザーエージェントは次の手順を実行する:
- 入力
-
candidate、largest contentful paint候補
intersectionRect、
DOMRectReadOnlypaintTimingInfo、paint timing info
loadTime、DOMHighResTimestamp
document、Document
- 出力
-
なし
-
documentのcontent setがcandidateを含んでいればリターン。
-
appendでcandidateをdocumentのcontent setに追加。
-
windowをdocumentのrelevant global objectとする。
-
windowのスクロールイベントがディスパッチされたかまたは入力イベントがディスパッチされたかがtrueなら、リターン。
-
sizeがdocumentのlargest contentful paint size 以下ならリターン。
-
urlを空文字列とする。
-
candidateのrequestがnullでなければ、 urlをcandidateのrequestの request URLにする。
-
idをcandidateのelementのelement idとする。
-
contentInfoをcontentInfo["size"] = size, contentInfo["url"] = url, contentInfo["id"] = id, contentInfo["loadTime"] = loadTime, contentInfo["element"] = candidateのelementとするmapとする。
-
LargestContentfulPaintエントリーの作成を contentInfo, paintTimingInfo, documentで実行する。
-
4.5. LargestContentfulPaintエントリーの作成
LargestContentfulPaint
エントリーの作成を行うには、ユーザーエージェントは次の手順を実行する:
- 入力
-
contentInfo、map
paintTimingInfo、paint timing info
document、
Document - 出力
-
なし
-
documentのlargest contentful paint sizeに contentInfo["size"]をセットする。
-
entryを新しい
LargestContentfulPaintエントリーとする。documentのrelevant realmで、paint timing infoはpaintTimingInfo、 さらに -
PerformanceEntryキュー entryを呼び出す。
-
5. セキュリティとプライバシーに関する考慮事項
このAPIは低レベルのプリミティブとしてPaint Timingに依存しています。同様のElement Timing APIと異なり、LCPはたとえ小さい要素であっても、ページ読み込み時点までで最大であればタイミング詳細を開示する可能性があります。しかし、これはElement Timingが既に可能にしている範囲を超えた機微な情報は公開しないと思われます。