1. はじめに
このセクションは規定ではありません。
ウェブブラウザの主な目的は、HTML、CSS、画像リソースをユーザーのために画面上のピクセルへ変換することです。ウェブページのパフォーマンス測定は、多くの場合、これらの作業(テキストや画像などのコンテンツを画面に描画する)の所要時間を計測することに関係します。こうしたタイミングの使い方には、ページのパフォーマンスやロード時のユーザー体験を評価する様々な方法がありますが、根本的にはどれも時間を測定する共通の手段から始まります。
これはペイントタイミングを一般的な仕組みとして測定する方法を定める基礎的なドキュメントです。この基盤を用いて、First Paint(最初のペイント)およびFirst Contentful Paint(最初の内容ペイント)の指標を定義します。ペイント測定の他の具体的な事例については、他の文書で定められる場合があります。
具体的に、本仕様では以下を扱います:
-
画像がデコードされペイント準備が整う時刻の測定
-
要素が描画される時刻の測定
-
描画された要素のサイズの測定
-
描画された要素が目に見えるコンテンツを含むかどうかの判定
1.1. 最初のペイントおよび最初の内容ペイント
ロードは単一の瞬間ではなく、単一の指標で完全に捉えられるものではありません。ロード体験には、ユーザーが「速い」と感じるか「遅い」と感じるかに影響する複数の瞬間があります。
First Paint(FP)はその重要な瞬間の最初であり、続いてFirst Contentful Paint(FCP)が続きます。これらの指標は、ブラウザが指定されたドキュメントを描画するタイミングを示します。これはユーザーにとって「何かが起きているか?」という疑問に答える重要な瞬間です。
両指標の主な違いは、FPがブラウザがそのドキュメントで何かを初めて描画した時点を示すのに対し、FCPはDOMから最初の画像またはテキストコンテンツが描画された時点を示すことです。
1.2. 使用例
const observer= new PerformanceObserver( function ( list) { const perfEntries= list. getEntries(); for ( const perfEntryof perfEntries) { // エントリーの処理 // 分析や監視のための報告 // ... } }); // ペイントタイミング通知のためのオブザーバ登録 observer. observe({ entryTypes: [ "paint" ]});
2. 用語
ペイント:ユーザーエージェントが「ペイント」(または「レンダー」)を実行したとは、レンダーツリーを画面上のピクセルに変換したことを指します。正式には、ユーザーエージェントがイベントループのレンダリングの更新ステップを実行したときに「レンダー」されたとみなします。
注意: レンダリング処理は非常に複雑であり、タイムスタンプはユーザーエージェントがこのパイプラインで記録できる最新のタイムスタンプ(ベストエフォート)であるべきです。通常、このAPIではフレームがOSへ表示のため送信される時刻が推奨されます。
生成コンテンツ疑似要素は、以下すべてを満たす場合ペイント可能疑似要素です:
-
疑似要素の 算出済み visibility は
visibleです。 -
疑似要素は非空のボックスを生成します。
CSS画像 imgは、以下すべてを満たす場合内容画像です:
DOMString
は、非空であるとは、文書の空白文字以外の文字を1文字以上含む場合です。
要素 targetは、次のいずれかを満たす場合内容有りです:
-
target は、テキストノード の子を持ち、その子は空でない テキストを表し、かつそのノードの使用 不透明度が 0 より大きい。
注記: これは、タイポグラフィ疑似要素がテキストノードの不透明度を 上書きする場合を含む。
-
target は、background-image を持ち、それがコンテンツを含む画像であり、かつその使用 background-size の幅と高さの値が 0 ではない。
-
target は、border-image-source を持ち、それがコンテンツを含む 画像であり、かつその使用 border-image-width の値が 0 ではない。
-
target は、
video要素であり、その表すものがポスターフレームまたは最初の動画フレームであり、そのフレームが利用可能である。 -
target は、レンダリングされる子孫を持つ svg 要素である。
-
target は、起点要素であり、描画可能な 疑似要素の起点となり、その疑似要素はコンテンツを含む画像または空でないテキストを表す。
要素は、以下のいずれかの場合タイミング対象です:
-
ある要素には background-image があり、それは コンテンツフル画像である。
-
テキストノード。
ペイント可能境界矩形を要素targetで計算するには、次の手順を実行します:
-
boundingRectを
getBoundingClientRect()をtargetで実行した結果とする。 -
boundingRectを返す。
注意: overflowやoverflowなボックスに含まれる要素は、ペイント可能境界矩形がクリップされません。どちらの場合でも、要素はスクロール操作で可視化できるためです。
要素 elは、次の全てを満たす場合ペイント可能です:
-
el はレンダリングされている。
-
el の使用 visibility は
visibleである。 -
el およびそのすべての祖先の使用 不透明度は 0 より大きい。
注記:
描画可能な要素が ユーザーに見えない場合があり得る。たとえば、テキストがその背景と同じ色である場合がこれに該当する。 これらの要素も、最初の コンテンツフルペイントを計算する目的では、引き続き描画可能であるとみなされる。 -
el の描画可能な境界矩形は、スクロール領域とdocumentの交差部分を持つ。
注記: これは、要素が サイズ 0 に拡大縮小されている場合、
displayである場合、または: nonedisplayであり、その内容が空の 矩形に解決される場合を含む。: contents注記: 一般則として、要素は、ビューポート内にある場合、または スクロールもしくはズームの結果としてビューポート内に入る可能性がある場合に描画可能である。
初回ペイントエントリーには、
DOMHighResTimeStamp
ナビゲーション後にユーザーエージェントが初めてレンダリングした時刻を報告するものが含まれる。これには既定の背景の
ペイントは含まれないが、既定以外の背景のペイントと、ペイント可能な
iframe の包含ボックスが含まれる。これは、開発者が
ページの読み込み時に重視する最初の重要な時点、すなわちユーザーエージェントがページのレンダリングを開始した時点である。
ブラウジングコンテキスト ctxは、以下のいずれかを満たす場合ペイントタイミング対象です:
-
ctxが最上位ブラウジングコンテキストである。
-
ctxが入れ子ブラウジングコンテキストで、ユーザーエージェントがctxにペイントタイミング報告を設定している。
注意: これにより、ユーザーエージェントはメインフレーム以外の一部フレームに対してのみペイントタイミングを有効化できます。例えば、ユーザーエージェントがメインフレームの情報を漏らす可能性がある場合、クロスオリジンiframeに対してペイントタイミングを無効化することもできます。
3. ペイントタイミングミキシン
このセクションは規範的ではありません。
PaintTimingMixin
インターフェイスは、レンダリングサイクルに関連するタイムスタンプを公開する。
これは、PerformanceEntry
を拡張するプラットフォームオブジェクトに含まれ、
具体的には PerformanceElementTiming、
LargestContentfulPaint、
PerformanceEventTiming、
PerformancePaintTiming、
および PerformanceLongAnimationFrameTiming
によって含まれる。
paintTime
属性は、レンダリングの更新ループの終了時点のタイムスタンプを表し、
presentationTime
は、フレームがユーザーに提示される際にマークされる実装固有のタイムスタンプを表します。
HTML標準でレンダリングの更新から呼び出されるペイントタイミングのマークアルゴリズムが両方の属性を設定します。
塗りタイミングに依存するエントリの属性、たとえば LargestContentfulPaint
の
renderTime
(および startTime)は、
通常、各個別のタイムスタンプではなくデフォルト塗りタイムスタンプを返すため、
presentationTime
の実装依存な性質に左右されません。
3.1. PaintTimingMixin
インターフェース
[Exposed =Window ]interface mixin {PaintTimingMixin readonly attribute DOMHighResTimeStamp ;paintTime readonly attribute DOMHighResTimeStamp ?; };presentationTime
PaintTimingMixin
インターフェースミキシンを含むオブジェクトには、関連付けられたペイントタイミング情報(nullまたはペイントタイミング情報)があります。
ペイントタイミング情報は、 構造体です。以下の項目を持ちます:
- レンダリング更新終了時刻
- 実装依存のプレゼンテーション時刻
-
Null または
DOMHighResTimeStamp
paintTime
属性のゲッターステップは、this
の ペイントタイミング情報 の レンダリング更新終了時間 を返します。
presentationTime
属性のゲッターステップは、存在する場合、this の ペイントタイミング情報 の 実装依存の提示時間 を返します。
ペイントタイミング情報 paintTimingInfo のデフォルトペイントタイムスタンプを取得するには、 paintTimingInfo の 実装依存の提示時間 が null でない場合はそれを返し、それ以外の場合は paintTimingInfo の レンダリング更新終了時間 を返します。
4. PerformancePaintTiming
インターフェイス
[Exposed =Window ]interface :PerformancePaintTiming PerformanceEntry { [Default ]object (); };toJSON PerformancePaintTiming includes PaintTimingMixin ;
PerformancePaintTiming
は PerformanceEntry
インターフェイスの下記属性を拡張します:
-
name属性のgetterは、最小限のフレーム属性付けのためにDOMStringを返さなければならない。name の値として考えられるものは次の通り:-
: first paint 用"first-paint" -
: first contentful paint 用"first-contentful-paint"
-
-
entryType属性のgetterはを返さなければならない。"paint" -
startTime属性のgetterは、塗りが発生した時刻のDOMHighResTimeStampを返さなければならない。 -
duration属性のgetterは 0 を返さなければならない。 -
toJSON が呼び出されたときは、 default toJSON steps を
PerformancePaintTiming用に実行する。
NOTE: PerformancePaintTiming
を実装するユーザーエージェントは、 を supportedEntryTypes
に含める必要があります。
グローバルオブジェクト の ブラウジングコンテキスト が paint-timing eligible である場合です。
これにより、開発者は特定の ブラウジングコンテキスト に対してペイントタイミングのサポートを検出できます。
5. 処理モデル
5.1. 関連付けられた画像リクエスト
各 Element
には 関連付けられた画像リクエスト があり、これは 画像リクエスト または null で、初期値は null です。
Element
型の element の処理モデルが
HTMLImageElement,
SVGImageElement,
または HTMLVideoElement
が新しい画像リソース(例:画像やポスター画像として表示されるため)を作成するとき、
element の 関連付けられた画像リクエスト は作成された画像リソースの 画像リクエスト に設定されます。
Note: URLの
scheme が "data" である画像リソースは、取得されませんが依然として読み込む必要がある 画像リクエスト
を持ちます。このリクエストは Element
の 関連付けられた画像リクエスト となり得ます。
Note: 現在の記述は具体的な アルゴリズムには言及していないため曖昧です。該当する処理モデルがより統一された処理モデルを持つ場合、より厳密に記述できます。
全ての Element
は 関連付けられた背景画像リクエスト
のリストを持ち、初期値は空の配列です。Element
element のスタイルが新しい画像リソース(背景画像として表示されるため)を必要とする場合、新しいリソースによって作成された 画像リクエスト が element の 関連付けられた背景画像リクエスト に追加されます。
NOTE: Element
は複数の 画像リクエスト を持つことができます。例えば、
background-image プロパティが複数値を持つ場合です。下記例では、一つの background-image プロパティが4つの
画像リクエスト を生成し、それぞれが下記アルゴリズムで記録・報告されます。
<!DOCTYPE html> < style > div { background-image : url( https://images.example/background1.png ), url( https://images.example/background2.png ); } </ style > < div ></ div > < div ></ div >
5.2. ペイントタイミングの記録
pending image record は、以下の 構造体の 要素を持つものです。
-
element、
Element -
request、画像リクエスト
-
loadTime,
DOMHighResTimeStamp
Element
は所有テキストノード集合(初期値は空の順序付き集合で、Text
ノードを含む)を持ちます。
Document
は過去に報告されたペイント集合(初期値は空の順序付き集合で、文字列を含む)を持ちます。
Document
はレンダリング待ち画像(初期値は空のリストで、保留画像レコードを含む)を持ちます。
Document
は描画済みテキストを持つ要素集合(初期値は空の順序付き集合で、Elementを含む)を持ちます。
5.2.1. CSS仕様への修正
画像リクエストがElementelementの関連背景画像リクエスト内で完全に利用可能となった場合、elementおよび画像リクエストを入力として読み込み完了画像の処理アルゴリズムを実行します。
5.2.2. HTML仕様への修正
Element
elementの関連画像リクエストが完全に利用可能となった場合、elementとその関連画像リクエストを入力として読み込み完了画像の処理アルゴリズムを実行します。
Text
ノードtextを初めてペイントしたとき、次の手順を実行してください:
-
textがフォントフェイスのフォントブロック期間のためにペイントされない場合は、戻る。
-
追加としてtextをelementの所有テキストノード集合に加える。
5.2.3. 読み込み完了画像の処理
Element
elementと画像リクエスト imageRequestを入力として実行するには:
-
rootをelementのルートとする。
-
rootが
Documentでなければ、戻る。 -
nowをelementの現在の高精度時刻(elementの関連グローバルオブジェクトに基づく)とする。
-
recordを保留画像レコード(element element、request imageRequest、loadTime now)とする。
-
recordをrootのレンダリング待ち画像に追加する。
5.3. ペイントタイミングの報告
5.3.1. 最初の内容ペイント
-
もし document の これまでに報告されたペイントの集合 が
を含む場合、false を返す。"first-contentful-paint" -
もし document が 要素を1つ以上保持しており、そのどれかが paintable かつ contentful であれば、true を返す。
-
それ以外の場合、false を返す。
5.3.2. ペイントタイミングのマーク
-
文書の閲覧コンテキストがペイントタイミングの対象でない場合、 戻る。
-
paintTimingInfo を新しいペイントタイミング情報とし、そのレンダリング更新終了時刻を 現在の高分解能時刻とする。この時刻は documentの関連するグローバルオブジェクトを指定して取得する。
-
paintedImages を新しい順序付き集合とする
-
paintedTextNodes を新しい順序付き集合とする
-
各recordについて、docのレンダリング待ちの 画像リストを反復する:
-
recordのリクエストが利用可能でペイントの準備が整っている場合、次の 手順を実行する:
-
recordをpaintedImagesに追加する。
-
recordをdocのレンダリング待ちの画像リストから削除する。
-
-
-
各
Elementelementについて、docの子孫を反復する:-
elementがdocのレンダリングされた テキストを持つ要素の集合に含まれる場合、次に進む。
-
elementの所有するテキストノードの集合が空の場合、 次に進む。
-
追加する。elementをdocのレンダリングされた テキストを持つ要素の集合に。
-
追加する。elementを paintedTextNodesに。
-
-
reportedPaintsをdocumentの以前に報告されたペイントの集合とする。
-
frameTimingInfoをdocumentの現在のフレームタイミング情報とする。
-
documentの現在のフレームタイミング情報を null に設定する。
-
flushPaintTimingsを次の手順とする:
-
reportedPaintsに
が含まれず、ユーザーエージェントが 初回 ペイントを記録するよう設定されている場合、ペイントタイミングを報告する。document、"first-paint" 、およびpaintTimingInfoを指定する。"first-paint" 注: 初回ペイントには既定の 背景のペイントは含まれないが、既定以外の背景のペイントは含まれる。
-
documentが初回コンテンツフル ペイントを報告すべき場合、次を実行する:
-
ペイントタイミングを報告する。指定するのは document、
、および paintTimingInfo。"first-contentful-paint"
注: 親フレームは 子 iframe のペイントイベントを認識すべきではなく、その逆も同様である。これは、 iframe のみを含むフレームには初回ペイント(ペイント可能な iframe の包含ボックスによる)が発生するが、初回コンテンツフルペイントは発生しないことを意味する。
注: 文書が
または"first-paint" を記録することは保証されない。完全に空白の文書は初回ペイントを記録しない場合があり、文書にコンテンツフルでない要素のみが含まれる場合、 初回コンテンツフルペイントが記録されないことがある。"first-contentful-paint" 注: 初回ペイントの 記録は任意である。ペイントタイミングを実装するユーザーエージェントは、少なくとも初回コンテンツフルペイントを記録すべきである。
-
-
最大コンテンツフルペイントを報告する。 document、paintTimingInfo、 paintedImagesおよびpaintedTextNodesを指定する。
-
要素タイミングを報告する。指定するのは document、paintTimingInfo、 paintedImagesおよびpaintedTextNodes。
-
frameTimingInfoが null でない場合、長いアニメーションフレームの エントリーをキューに入れる。document、frameTimingInfo、および paintTimingInfoを指定する。
-
-
ユーザーエージェントが実装定義の表示時刻をサポートしない場合、 flushPaintTimingsを呼び出して戻る。
-
次の手順を並列に実行する:
-
現在のフレームがユーザーに表示された時点を表す実装定義の時刻になるまで 待機する。
-
paintTimingInfoの実装定義の 表示時刻を、現在の高分解能時刻に設定する。 この時刻はdocumentの関連するグローバルオブジェクトを指定して取得する。
-
documentのオリジン間 分離機能が false の場合、次を実行する:
-
paintTimingInfoの実装定義の 表示時刻を、次の4ミリ秒の倍数、またはそれより粗い精度に丸める。
-
現在の高分解能 時刻がpaintTimingInfoの実装定義の 表示時刻になるまで待機する。
-
-
グローバルタスクをキューに入れる。対象となるパフォーマンスタイムラインのタスク ソースに、documentの関連するグローバルオブジェクトを指定し、 flushPaintTimingsを実行する。
-
5.3.3. ペイントタイミングの報告
-
新しい
PerformancePaintTimingオブジェクトnewEntryをdocumentの関連レルムで作成し、以下の属性を設定する:-
newEntryの
name属性にpaintTypeを設定。 -
newEntryの
entryType属性にを設定。"paint" -
newEntryの
startTime属性にデフォルトペイントタイムスタンプ(paintTimingInfoで取得)を設定。 -
newEntryの
duration属性に0を設定。
-
-
newEntryのペイントタイミング情報にpaintTimingInfoを設定。
-
追加としてpaintTypeをdocumentの過去に報告されたペイント集合に加える。
5.4. 共通アルゴリズム
5.4.1. ペイントタイミング向け公開
要素elementがペイントタイミングのために露出されているかどうか判定するには、Documentまたはnullであるdocumentを使い、次の手順を実行する:
-
elementが接続済みでなければ、falseを返す。
-
documentがnullの場合、documentをelementの関連設定オブジェクトの関連グローバルオブジェクトの関連付けられたdocumentとする。
-
documentが完全にアクティブでなければ、falseを返す。
-
elementのルートがdocumentと一致しなければ、falseを返す。
-
trueを返す。
6. 謝辞
この仕様の技術的な貢献・提案を通じて改善に導いてくださった全てのコントリビューターに特別な感謝を表します。