-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathindex.bs
439 lines (340 loc) · 25.4 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
<pre class='metadata'>
Title: Paint Timing
Group: webperf
Shortname: paint-timing
Level: none
ED: https://w3c.github.io/paint-timing/
TR: https://www.w3.org/TR/paint-timing/
Status: ED
Editor: Ian Clelland, Google https://google.com, [email protected], w3cid 76841
Noam Rosenthal, Invited Expert, [email protected], w3cid 121539
Former Editor: Shubhie Panicker, Google https://google.com, [email protected], w3cid 92587
Nicolás Peña Moreno, Google https://google.com, [email protected], w3cid 103755
Repository: w3c/paint-timing
Abstract: This document defines an API that can be used to capture a series of key moments (first paint, first contentful paint) during pageload which developers care about.
Default Highlight: js
</pre>
<pre class=link-defaults>
spec:dom; type:dfn; text:descendant
spec:dom; type:dfn; text:element
spec:css22; type:dfn; text:visibility
</pre>
<pre class=anchors>
urlPrefix: https://html.spec.whatwg.org/multipage/images.html
type: dfn; text: available; url: #img-available;
type: dfn; text: image; url: #images;
urlPrefix: https://www.w3.org/TR/SVG2/render.html; spec: CR-SVG2
type: dfn; url: #Rendered-vs-NonRendered; text: svg element with rendered descendants;
urlPrefix: https://www.w3.org/TR/css-backgrounds-3/; spec: CSS-BACKGROUNDS-3;
type: dfn; text: background-image; url: #propdef-background-image;
type: dfn; text: background-size; url: #background-size;
urlPrefix: https://html.spec.whatwg.org/multipage/canvas.html; spec: HTML;
type: dfn; text: context mode; url: #concept-canvas-context-mode;
urlPrefix: https://html.spec.whatwg.org/multipage/images.html; spec: HTML;
type: dfn; text: completely available; url: #img-all;
urlPrefix: https://html.spec.whatwg.org/multipage/rendering.html; spec: HTML;
type: dfn; text: being rendered; url: #being-rendered;
urlPrefix: https://w3c.github.io/IntersectionObserver/
type: dfn; text: Intersection rect algorithm; url: #calculate-intersection-rect-algo
urlPrefix: https://html.spec.whatwg.org/multipage/dom.html
type: dfn; text: represents; url: #represents;
urlPrefix: https://drafts.csswg.org/css-pseudo-4
type: dfn; text: generated content pseudo-element; url: #generated-content;
type: dfn; text: typographical pseudo-element; url: #typographic-pseudos;
urlPrefix: https://drafts.csswg.org/css2/zindex.html; spec: CSS;
type: dfn; url:#painting-order; text: painting order;
urlPrefix: https://www.w3.org/TR/cssom-view
type: dfn; text: scrolling area; url: #scrolling-area;
urlPrefix: https://www.w3.org/TR/css3-values/
type: dfn; text: url valued; url: #url-value;
urlPrefix: https://drafts.fxtf.org/css-masking-1/
type: dfn; text: clip-path; url: #the-clip-path;
urlPrefix: https://www.w3.org/TR/css-images-3/
type: dfn; text: CSS image; url: #typedef-image;
urlPrefix: https://html.spec.whatwg.org/multipage/media.html
type: dfn; text: poster frame; url: #poster-frame;
urlPrefix: https://html.spec.whatwg.org/multipage/browsers.html
type: dfn; text: browsing context; url: #browsing-context;
type: dfn; text: nested browsing context; url: #nested-browsing-context;
urlPrefix: https://fetch.spec.whatwg.org/; spec: FETCH;
type: dfn; url:#concept-tao-check; text: timing allow check;
urlPrefix: https://wicg.github.io/largest-contentful-paint/; spec: ELEMENT-TIMING
type: dfn; url:#report-largest-contentful-paint; text: Report largest contentful paint
urlPrefix: https://wicg.github.io/element-timing/; spec: ELEMENT-TIMING
type: dfn; url:#report-element-timing; text: Report element timing
urlPrefix: https://w3c.github.io/long-animation-frame/; spec: LONG-ANIMATION-FRAME
type: dfn; url:#queue-a-long-animation-frame-entry; text: Queue a long animation frame entry
type: dfn; text: current frame timing info
</pre>
Introduction {#intro}
=====================
<div class=non-normative>
<em>This section is non-normative.</em>
Much of the purpose of a web browser is to translate HTML, CSS and image
resources into pixels on a screen for users. Measuring the performance of a web
page often involves measuring the time it takes to perform these tasks - to
render content, whether text or image, to the screen. There are many different
ways to use this timing to make statemements about the performance of a page,
or about the user experience of loading, but fundamentally all of those ways
begin with a common means of measuring time.
This is a foundational document which specifies how to measure paint timing as a
general-purpose mechanism. That foundation is then used to define the First
Paint and First Contentful Paint metrics. Other specific instances of paint
measurement may be specified in other documents.
Specifically, this specification covers:
* Measuring the time when images are decoded and ready for painting
* Measuring the time when elements are painted
* Measuring the size of the painted elements
* Determining whether a painted element contains any visible content.
First Paint and First Contentful Paint {#first-paint-and-first-contentful-paint}
--------------------------------------------------------------------------------
Load is not a single moment in time — it's an experience that no one metric can fully capture. There are multiple moments during the load experience that can affect whether a user perceives it as "fast" or "slow".
First paint (FP) is the first of these key moments, followed by first contentful paint (FCP). These metrics mark the points in time when the browser renders a given document. This is important to the user because it answers the question: is it happening?
The primary difference between the two metrics is FP marks the first time the browser renders anything for a given document. By contrast, FCP marks the time when the browser renders the first bit of image or text content from the DOM.
Usage example {#example}
------------------------
<pre class="example highlight">
const observer = new PerformanceObserver(function(list) {
const perfEntries = list.getEntries();
for (const perfEntry of perfEntries) {
// Process entries
// report back for analytics and monitoring
// ...
}
});
// register observer for paint timing notifications
observer.observe({entryTypes: ["paint"]});
</pre>
</div>
Terminology {#sec-terminology}
==============================
<dfn export>Paint</dfn>: the user agent has performed a "paint" (or "render") when it has converted the render tree to pixels on the screen.
Formally, we consider the user agent to have "rendered" a document when it has performed the [=update the rendering=] steps of the event loop.
NOTE: The rendering pipeline is very complex, and the timestamp should be the latest timestamp the user agent is able to note in this pipeline (best effort). Typically the time at which the frame is submitted to the OS for display is recommended for this API.
A [=generated content pseudo-element=] is a <dfn>paintable pseudo-element</dfn> when all of the following apply:
* The pseudo-element's [=used value|used=] [=visibility=] is <code>visible</code>.
* The pseudo-element's [=used value|used=] [=opacity=] is greater than zero.
* The pseudo-element generates a non-empty [=box=].
A [=CSS image=] |img| is a <dfn>contentful image</dfn> when all of the following apply:
* |img| is [=url valued=].
* |img| is [=available=].
A {{DOMString}} is <dfn>non-empty</dfn> if it contains at least one character excluding [=document white space characters=].
An [=/element=] |target| is <dfn export>contentful</dfn> when one or more of the following apply:
* |target| has a [=text node=] child, representing [=non-empty=] text, and the node's [=used value|used=] [=opacity=] is greater than zero.
NOTE: this covers the case where a [=typographical pseudo-element=] would override the opacity of the text node.
* |target| is a [=replaced element=] representing an [=available=] [=image=].
* |target| has a [=background-image=] which is a [=contentful image=], and its [=used value|used=] [=background-size=] has non-zero width and height values.
* |target| is a <{canvas}> with its [=context mode=] set to any value other than <code>none</code>.
* |target| is a <{video}> element that [=represents=] its [=poster frame=] or the first video frame and the frame is available.
* |target| is an [=svg element with rendered descendants=].
* |target| is an <{input}> element with a [=non-empty=] <{input/value}> attribute.
* |target| is an [=originating element=] for a [=paintable pseudo-element=] that represents a [=contentful image=] or [=non-empty=] text.
An [=/element=] is <dfn export>timing-eligible</dfn> if it is one of the following:
* an <{img}> element.
* an <{image}> element inside an <{svg}> element.
* a <{video}> element with a [=poster frame=].
* an element with a [=contentful image|contentful=] <a>background-image</a>.
* a text node.
To compute the <dfn>paintable bounding rect</dfn> of [=/element=] |target|, run the following steps:
1. Let |boundingRect| be the result of running the {{Element/getBoundingClientRect()}} on |target|.
1. Clip |boundingRect| with the [=document=]'s [=scrolling area=].
1. Return |boundingRect|.
NOTE: elements contained by boxes with <code>overflow: scroll</code> or <code>overflow: hidden</code> don't have their [=paintable bounding rect=] clipped, as in both cases the [=/element=] can become visible by scrolling.
An [=/element=] |el| is <dfn>paintable</dfn> when all of the following apply:
* |el| is [=being rendered=].
* |el|'s [=used value|used=] [=visibility=] is <code>visible</code>.
* |el| and all of its ancestors' [=used value|used=] [=opacity=] is greater than zero.
NOTE: there could be cases where a <code>paintable</code> [=/element=] would not be visible to the user, for example in the case of text that has the same color as its background.
Those elements would still considered as paintable for the purpose of computing [=first contentful paint=].
* |el|'s [=paintable bounding rect=] intersects with the [=scrolling area=] of the [=document=].
NOTE: This covers the cases where the element is scaled to zero size, has <code>display: none</code>, or <code>display: contents</code> where the contents resolve to an empty rect.
NOTE: As a general rule, an [=/element=] is paintable if it is within the viewport, or can potentially be in the viewport as a result of scrolling or zooming.
<dfn export>First paint</dfn> entry contains a {{DOMHighResTimeStamp}} reporting the time when the user agent first rendered after navigation. This excludes the default background paint, but includes non-default background paint and the enclosing box of an iframe. This is the first key moment developers care about in page load – when the user agent has started to render the page.
A [=browsing context=] |ctx| is <dfn>paint-timing eligible</dfn> when one of the following apply:
* |ctx| is a [=top-level browsing context=].
* |ctx| is a [=nested browsing context=], and the user agent has configured |ctx| to report paint timing.
NOTE: this allows user agents to enable paint-timing only for some of the frames, in addition to the main frame, if they so choose.
For example, a user agent may decide to disable paint-timing for cross-origin iframes, as in some scenarios their paint-timing might reveal information about the main frame.
The {{PaintTimingMixin}} interface {#sec-PaintTimingMixin}
<pre class="idl">
[Exposed=Window]
interface mixin PaintTimingMixin {
readonly attribute DOMHighResTimeStamp paintTime;
readonly attribute DOMHighResTimeStamp? presentationTime;
};
</pre>
Objects including the {{PaintTimingMixin}} interface mixin have an associated <dfn for=PaintTimingMixin>paint timing info</dfn> (null or a [=/paint timing info=]).
<dfn export>paint timing info</dfn> is a [=struct=]. It has the following [=struct/items=]:
<dl dfn-for="paint timing info">
: <dfn>rendering update end time</dfn>
:: A {{DOMHighResTimeStamp}}
: <dfn>implementation-defined presentation time</dfn>
:: Null or a {{DOMHighResTimeStamp}}
</dl>
The {{PaintTimingMixin/paintTime}} attribute's getter step is to return [=/this=]'s [=PaintTimingMixin/paint timing info=]'s [=paint timing info/rendering update end time=].
The {{PaintTimingMixin/presentationTime}} attribute's getter step, if exists, is to return [=/this=]'s [=PaintTimingMixin/paint timing info=]'s [=paint timing info/implementation-defined presentation time=].
To get the <dfn>default paint timestamp</dfn> for a [=/paint timing info=] |paintTimingInfo|, return |paintTimingInfo|'s [=implementation-defined presentation time=] if it is non-null, otherwise |paintTimingInfo|'s [=rendering update end time=].
The {{PerformancePaintTiming}} interface {#sec-PerformancePaintTiming}
=======================================
<pre class="idl">
[Exposed=Window]
interface PerformancePaintTiming : PerformanceEntry {};
PerformancePaintTiming includes PaintTimingMixin;
</pre>
{{PerformancePaintTiming}} extends the following attributes of {{PerformanceEntry}} interface:
* The {{PerformanceEntry/name}} attribute's getter must return a {{DOMString}} for minimal frame attribution. Possible values of name are:
* <code>"first-paint"</code>: for [=first paint=]
* <code>"first-contentful-paint"</code>: for [=first contentful paint=]
* The {{PerformanceEntry/entryType}} attribute's getter must return <code>"paint"</code>.
* The {{PerformanceEntry/startTime}} attribute's getter must return a {{DOMHighResTimeStamp}} of when the paint occured.
* The {{PerformanceEntry/duration}} attribute's getter must return 0.
NOTE: A user agent implementing {{PerformancePaintTiming}} would need to include <code>"paint"</code> in {{PerformanceObserver/supportedEntryTypes}} of a [=realm/global object=] whose [=Window/browsing context=] is [=paint-timing eligible=].
This allows developers to detect support for paint timing for a particular [=browsing context=].
Processing model {#sec-processing-model}
========================================
Associated Image Requests {#sec-associated-image-requests}
----------------------------------------------------------
Each {{Element}} has an <dfn>associated image request</dfn> which is an [=image
request=] or null, initially null.
When the processing model for an {{Element}} <em>element</em> of type
{{HTMLImageElement}}, {{SVGImageElement}}, or {{HTMLVideoElement}} creates a
new image resource (e.g., to be displayed as an image or poster image),
<em>element</em>'s <a>associated image request</a> is set to the <a>image
request</a> of the created image resource.
Note: Every image resource that is obtained from a URL whose
<a spec=url>scheme</a> is equal to "data" has an associated <a>image request</a>
which is not fetched but still needs to be loaded. This request can be the
<a>associated image request</a> of an {{Element}}.
Note: The current language is vague since it does not point to specific
algorithms. This can be made more rigorous when the corresponding processing
models have a more unified processing model.
Every {{Element}} has a list of <dfn>associated background image requests</dfn>
which is initially an empty array. When the processing model for the {{Element}}
<em>element</em>'s style requires a new image resource (to be displayed as
background image), the <a>image request</a> created by the new resource is
appended to <em>element</em>'s <a>associated background image requests</a>.
NOTE: An {{Element}} can have several [=image requests=], e.g. if its
<a>background-image</a> property has multiple values. For instance, in the
following example, a single <a>background-image</a> property produces four
[=image requests=], each of which will be recorded and reported by the
algorithms below.
```html
<!DOCTYPE html>
<style>
div {
background-image: url(https://images.example/background1.png),
url(https://images.example/background2.png);
}
</style>
<div></div>
<div></div>
```
Recording paint timing {#sec-recording-paint-timing}
--------------------------------------------------------
A <dfn>pending image record</dfn> is a [=struct=] with the following
[=struct/items=]:
* <dfn for="pending image record">element</dfn>, an {{Element}}
* <dfn for="pending image record">request</dfn>, an [=image request=]
* <dfn for="pending image record">loadTime</dfn>, a {{DOMHighResTimeStamp}}
Each {{Element}} has a <dfn>set of owned text nodes</dfn>, which is an [=ordered set=] of {{Text}} nodes, initially empty.
Each {{Document}} has a <dfn>set of previously reported paints</dfn>, which is an [=ordered set=] of [=strings=], initially empty.
Each {{Document}} has an <dfn>images pending rendering</dfn>, which is a [=/list=] of [=pending image records=], initally empty.
Each {{Document}} has a <dfn>set of elements with rendered text</dfn>, which is an [=ordered set=] of {{Element}}s, initially empty.
<h4 id="sec-modifications-CSS">Modifications to the CSS specification</h4>
Whenever an <a>image request</a> in an {{Element}} <em>element</em>'s <a>associated background image requests</a> becomes <a>completely available</a>, run the algorithm to <a>process an image that finished loading</a> with <em>element</em> and <a>image request</a> as inputs.
<h4 id="sec-modifications-dom">Modifications to the HTML specification</h4>
When an {{Element}} <em>element</em>'s <a>associated image request</a> has become <a>completely available</a>, run the algorithm to <a>process an image that finished loading</a> passing in <em>element</em> and its <a>associated image request</a> as inputs.
<div algorithm="text aggregation">
When the user agent paints a {{Text}} node |text| for the first time, it should execute the following steps:
* If |text| will not be painted due to the font face being in its <a>font block period</a>, then return.
* Let |element| be the {{Element}} which determines the <a>containing block</a> of |text|.
* <a for="set">Append</a> |text| to |element|'s <a>set of owned text nodes</a>.
</div>
<h4 dfn>Process image that finished loading</h4>
<div algorithm="image element loaded">
To <dfn>process an image that finished loading</dfn> given an {{Element}} |element| and an [=image request=] |imageRequest|:
1. Let |root| be |element|'s [=tree/root=].
1. If |root| is not a {{Document}}, return.
1. Let |now| be the [=current high resolution time=] given |element|'s <a>relevant global object</a>.
1. Let |record| be a [=pending image record=] with [=pending image record/element=] |element|, [=pending image record/request=] |imageRequest| and [=pending image record/loadTime=] |now|.
1. Add |record| to |root|'s [=images pending rendering=].
</div>
Reporting paint timing {#sec-reporting-paint-timing}
--------------------------------------------------------
<h4 dfn export>First Contentful Paint</h4>
<div algorithm="Should report first contentful paint">
To know whether [=Document=] |document| <dfn>should report first contentful paint</dfn>, perform the following steps:
1. If |document|'s [=set of previously reported paints=] contains <code>"first-contentful-paint"</code>, then return false.
1. If |document| contains at least one [=/element=] that is both [=paintable=] and [=contentful=], then return true.
1. Otherwise, return false.
</div>
<h4 dfn export>Mark paint timing</h4>
<div algorithm="Mark paint timing">
When asked to [=mark paint timing=] given a [=Document=] |document| as input, perform the following steps:
1. If the [=document=]'s [=Document/browsing context=] is not [=paint-timing eligible=], return.
1. Let |paintTimingInfo| be a new [=/paint timing info=], whose [=rendering update end time=] is the [=current high resolution time=] given |document|'s [=relevant global object=].
1. Let |paintedImages| be a new [=ordered set=]
1. Let |paintedTextNodes| be a new [=ordered set=]
1. For each |record| in |doc|'s [=images pending rendering=] list:
1. If |record|'s [=pending image record/request=] is [=available=] and ready to be painted, then run the following steps:
1. Append |record| to |paintedImages|.
1. Remove |record| from |doc|'s <a>images pending rendering</a> list.
1. For each {{Element}} |element| in |doc|'s <a>descendants</a>:
1. If |element| is contained in |doc|'s <a>set of elements with rendered text</a>, continue.
1. If |element|'s <a>set of owned text nodes</a> is empty, continue.
1. [=set/Append=] |element| to |doc|'s <a>set of elements with rendered text</a>.
1. [=set/Append=] |element| to |paintedTextNodes|.
1. Let |reportedPaints| be the |document|'s [=set of previously reported paints=].
1. Let |frameTimingInfo| be |document|'s [=current frame timing info=].
1. Set |document|'s [=current frame timing info=] to null.
1. Let |flushPaintTimings| be the following steps:
1. If |reportedPaints| does not contain <code>"first-paint"</code>, and the user agent is configured to mark [=first paint=], then [=report paint timing=] given |document|, <code>"first-paint"</code>, and |paintTimingInfo|.
NOTE: [=First paint=] excludes the default background paint, but includes non-default background paint.
ISSUE: This should be turned into a normative note.
1. If |document| [=should report first contentful paint=], then:
1. [=Report paint timing=] given |document|, <code>"first-contentful-paint"</code>, and |paintTimingInfo|.
NOTE: A parent frame should not be aware of the paint events from its child iframes, and vice versa. This means that a frame that contains just iframes will have [=first paint=] (due to the enclosing boxes of the iframes) but no [=first contentful paint=].
NOTE: A [=document=] is not guaranteed to mark <code>"first-paint"</code> or <code>"first-contentful-paint"</code>. A completely blank [=document=] may never mark [=first paint=], and a [=document=] containing only elements that are not [=contentful=] may never mark [=first contentful paint=].
NOTE: The marking of [=first paint=] is optional. User-agents implementing paint timing should at the very least mark [=first contentful paint=].
1. [=Report largest contentful paint=] given |document|, |paintTimingInfo|,
|paintedImages| and |paintedTextNodes|.
1. [=Report element timing=] given |document|, |paintTimingInfo|,
|paintedImages| and |paintedTextNodes|.
1. If |frameTimingInfo| is not null, then [=queue a long animation frame entry=] given |document|, |frameTimingInfo|, and |paintTimingInfo|.
1. If the user-agent does not support implementation-defined presentation times, call |flushPaintTimings| and return.
1. Run the following steps [=In parallel=]:
1. Wait until an implementation-defined time when the current frame has been presented to the user.
1. Set |paintTimingInfo|'s [=implementation-defined presentation time=] to the [=current high resolution time=] given |document|'s [=relevant global object=].
1. If |document|'s [=environment settings object/cross-origin isolated capability=] is false, then:
1. Coarsen |paintTimingInfo|'s [=implementation-defined presentation time=] to the next multiple of 4 milliseconds, or coarser.
1. Wait until the [=current high resolution time=] is |paintTimingInfo|'s [=implementation-defined presentation time=].
1. [=Queue a global task=] on the [=performance timeline task source=] given |document|'s [=relevant global object=] to run |flushPaintTimings|.
</div>
<h4 dfn>Report paint timing</h4>
<div algorithm="Report paint timing">
To [=report paint timing=] given |document|, |paintType|, and a [=/paint timing info=] |paintTimingInfo| as arguments, perform the following steps:
1. Create a <a spec=webidl>new</a> {{PerformancePaintTiming}} object |newEntry| with |document|'s [=relevant realm=] and set its attributes as follows:
1. Set |newEntry|'s {{PerformanceEntry/name}} attribute to |paintType|.
1. Set |newEntry|'s {{PerformanceEntry/entryType}} attribute to <code>"paint"</code>.
1. Set |newEntry|'s {{PerformanceEntry/startTime}} attribute to the [=default paint timestamp=] given |paintTimingInfo|.
1. Set |newEntry|'s {{PerformanceEntry/duration}} attribute to 0.
1. Set |newEntry|'s [=PaintTimingMixin/paint timing info=] to |paintTimingInfo|.
1. [=queue a PerformanceEntry|Queue=] |newEntry| in |document|'s [=relevant realm=].
1. [=list/Append=] |paintType| to |document|'s [=set of previously reported paints=].
</div>
Common algorithms {#sec-common-algorithms}
------------------------------------------
<h4 dfn export>Exposed for paint timing</h4>
<div algorithm="Exposed for paint timing">
To determine whether an [=/Element=] |element| is [=exposed for paint timing=], given a [=Document=] or null |document|, perform the following steps:
1. If |element| is not [=connected=], return false.
1. If |document| is null, let |document| be |element|'s [=relevant settings object=]'s [=relevant global object=]'s [=associated document=].
1. If |document| is not [=fully active=], return false.
1. If |element|'s [=tree/root=] is not equal to |document|, return false.
1. Return true.
</div>
<!-- ============================================================ -->
<h2 id=acknowledgements>Acknowledgements</h2>
<!-- ============================================================ -->
Special thanks to <a href="https://github.com/w3c/paint-timing/graphs/contributors">all the contributors</a> for their technical input and suggestions that led to improvements to this
specification.