-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Long Animation Frame (LoAF) explainer #100
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exciting!
loaf-explainer.md
Outdated
|
||
- Time spent in forced layout/style calculations - e.g. calling `getBoundingClientRect`, doing more processing, and then rendering (also known as "layout thrashing" or "forced reflow"). | ||
- How many rendering opportuinities were missed - counting points in time where the browser was ready to receive a new paint but the main thread was busy with this LoAF. | ||
- Is the frame blocking animation/input-feedback *in practice*. Note that a frame that blocks actual UI events would also be accessible via [event timing](https://w3c.github.io/event-timing/). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Animations are very complicated, to the point that we should consider not including them in scope.
Many animations are declarative and not driven by main thread updates. Many animations start/stop into sequences of frames, and it tends to be more useful to consider the overall effect of long sequences of frames.
Once we have LoAF reporting, I think it will make it easier to revisit this problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(though, when it comes to attribution, perhaps some signal about "had animation" or "had event" would be useful)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, that's what I was thinking
loaf-explainer.md
Outdated
entryType: "long-animation-frame", | ||
|
||
// https://html.spec.whatwg.org/#event-loop-processing-model, see |taskStartTime| | ||
startTime: taskStartTime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this be the first task, first long task, or first task with some invalidation/rendering change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...the pseudocode at the bottom answered this question... it would be the last task before rendering.
The theory is that rendering always follows a long task, and that a bunch of small tasks cannot collectively add up to a long frame.
I think these can be tested over time, but I think its a reasonable hypothesis to start with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I changed this - it's wrong. It should be the first task after the last "update the rendering" that had a rendering opportunity.
loaf-explainer.md
Outdated
|
||
// The number of times there was a render opportunity but the main thread was busy | ||
// processing this frame | ||
discardedRenderOpportunities, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative: expose the previous paintTiming (in case the previous animation frame was not long).
Or, maybe duration is entirely sufficient.
loaf-explainer.md
Outdated
discardedRenderOpportunities, | ||
|
||
// Whether this long frame was blocking input/animation in practice | ||
blocking: 'ui-event' | 'animation' | 'none', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can have ui-event and animation at the same time...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think in that case we'd say we're blocking a UI event.
const startTime = performance.now(); | ||
const task = eventQueue.pop(); | ||
if (task) | ||
task.run(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you mentioned-- there is some surprising detail here, in that task.run()
can do a lot more than perhaps expected, including run other, nested "event loops", such as dispatching UI events.
Also includes microtasks.
loaf-explainer.md
Outdated
|
||
### Some notes about processing | ||
|
||
1. relying on "discarded rendering opportunities" as the qualifier for sluggishness alongside (or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part feels more risky and out of place than the bulk on the proposal. I would consider decoupling animations to the future.
Regarding measurement and tab visibility -- I would consider factoring something like rendering priority, instead? There are time periods when rendering is high, normal, or low/no priority. Perhaps we treat these differently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rendering priority is an unspecified implementation-specific thing.
I think at least to begin with I'd keep it well lit and only measure active visible documents that remain that way throughout the frame.
Fix spelling errors in loaf-explainer.md
Maybe we can merge this into main some time? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits but otherwise LGTM
Add explainer for long-task revamp
See w3c/event-timing#122 and #89