Skip to content

Commit d29c12f

Browse files
authored
Update loaf-explainer.md
1 parent 9fe9106 commit d29c12f

File tree

1 file changed

+17
-32
lines changed

1 file changed

+17
-32
lines changed

loaf-explainer.md

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# Long Animation Frames (LoAF)
22
Long Tasks Revamped
33

4-
## Disclaimer
5-
This is work in progress. Feedback welcome, lots of things might change etc.
6-
74
## Overview
85

96
"Sluggishness" - the feeling that "this page is not responsive to interactions", is a common problem for users on the web today.
@@ -206,18 +203,19 @@ while (true) {
206203
}
207204
```
208205

209-
## How a LoAF entry might look like
206+
## How a LoAF entry looks like
210207
```js
211208
const someLongAnimationFrameEntry = {
212209
entryType: "long-animation-frame",
213210

214-
//
211+
// The start time of the first task that initiated the long animation frame.
215212
startTime,
216213

217214
// https://html.spec.whatwg.org/#event-loop-processing-model (17)
218215
// This is a well-specified and interoperable time, but doesn't include presentation time.
219216
// It's the time after all the animations and observers are done, style and layout are done,
220-
// and all that's left is painting & compositing.
217+
// and all that's left is painting & compositing. In the case of a task that didn't end up
218+
// updating the rendering, this would be the long task duration.
221219
duration,
222220

223221
// https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering
@@ -233,16 +231,6 @@ const someLongAnimationFrameEntry = {
233231
// ResizeObserver callbacks
234232
styleAndLayoutStart,
235233

236-
// The time the animation frame was queued. This could be before startTime, which means that
237-
// the animation frame was delayed, or after, which means that it was deferred - several updates
238-
// were batched together before scheduling a frame.
239-
desiredRenderStart,
240-
241-
// The implementation-specific time when the frame was actually presented. Should be anytime
242-
// between the previous task's |paintTime| and this task's |taskStartTime|.
243-
// (Not implemented yet)
244-
presentationTime,
245-
246234
// Time of the first UI event (mouse/keyboard etc.) to be handled during the course of this
247235
// frame. The timestamp is the event's
248236
// [timestamp](https://dom.spec.whatwg.org/#dom-event-timestamp), i.e. the time it was queued
@@ -262,9 +250,9 @@ const someLongAnimationFrameEntry = {
262250
// Note that these scripts are entry points to JS: the place where the platform calls a script.
263251
scripts: [
264252
{
265-
// The different script types help us understand the scenario from which the long script
253+
// The different script invoker types help us understand the scenario from which the long script
266254
// was invoked
267-
type:
255+
invokerType:
268256
// A known callback registered from a web platform API, e.g. setTimeout,
269257
// requestAnimationFrame.
270258
"user-callback" |
@@ -280,14 +268,14 @@ const someLongAnimationFrameEntry = {
280268
"classic-script" |
281269
"module-script"
282270

283-
// The name tries to give as much information about the *invoker* of the script.
271+
// The invoker tries to give as much information about the *invoker* of the script.
284272
// For callbacks: Object.functionName of the invoker, e.g. Window.setTimeout
285273
// For element event listeners: TAGNAME#id.onevent, or TAGNAME[src=src].onevent
286274
// For script blocks: the script source URL
287275
// For promises: The invoker of the promise, e.g. Window.fetch.then
288276
// Note that for promise resolvers, all of the handlers of the promise are mixed
289277
// together as one long script.
290-
name: "IMG#id.onload" | "Window.requestAnimationFrame" |
278+
invoker: "IMG#id.onload" | "Window.requestAnimationFrame" |
291279
"Response.json.then",
292280

293281
// when the function was invoked. Note that this is the startTime of the script, not
@@ -305,9 +293,8 @@ const someLongAnimationFrameEntry = {
305293
// Total time spent in forced layout/style inside this function
306294
forcedStyleAndLayoutDuration,
307295

308-
// The time when the callback was queued, e.g. the event timeStamp or the time when
309-
// the timeout was supposed to be invoked.
310-
desiredExecutionStart,
296+
// Total time spent in "pausing" synchronous operations (alert, synchronous XHR)
297+
pauseDuration,
311298

312299
// In the case of promise resolver this would be the invoker's source location
313300
// Note that we expose character position rather than line/column to avoid overhead of line splitting.
@@ -336,9 +323,13 @@ cross-origin (same-agent). The details about rendering the frame, such as
336323
rendered serially. That's because this information is already observable, by using
337324
`requestAnimationFrame` and `ResizeObserver` and measuring the delay between them. The premise is
338325
that global "update the rendering" timing information is already observable across same-agent
339-
windows, so exposing it directly does not leak new cross-origin information. However, the idea
340-
exposing less information to cross-origin same-agent subframes (as in, expose the rendering info
341-
only to the main frame) is open for discussion.
326+
windows, so exposing it directly does not leak new cross-origin information.
327+
328+
On top of that, LoAF only exposes this timing when the animation frame is long, while using the
329+
existing techniques can measure this timing also for short animation frames.
330+
331+
To conclude, this new API exposes cross-origin same-agent information that is currently already
332+
available and not protected, and in a lower fidelity than existing APIs.
342333

343334
### Notes, complexity, doubts, future ideas, TODOs
344335

@@ -360,15 +351,9 @@ a bit different but relies on similar principles:
360351
or rely on "discarded rendering opportunities" as the qualifier for sluggishness alongside (or
361352
instead of) millisecond duration.
362353

363-
1. Consider separating layout & style durations.
364-
365354
1. Exposing source locations might be a bit tricky or implementation defined.
366355
This can be an optional field but in any case requires some research.
367356

368-
1. Clarify how this correlates to [JS Profiler markers](https://github.com/WICG/js-self-profiling/blob/main/markers.md). In general performance observer aspire to be expose succinct important information with
369-
minimal overhead, while profiling exposes "everything" with some more overhead, but the differences
370-
and relationship can be further understood.
371-
372357
## Relationship with TBT
373358

374359
TBT ([total blocking time](https://web.dev/tbt/)) is a metric that allows measuring how responsive/sluggish the experience is during page load.

0 commit comments

Comments
 (0)