Closed renspoesse closed 1 year ago
@bodymovin this implements https://github.com/airbnb/lottie-web/issues/2906.
Hey this is great!
I have two questions.
Why do you need to replace all the types to interfaces?
What are you using the drawnFrame
event for? It is intended as an internal event so I could pass the drawing instructions from the worker to the main thread.
This may not be relevant in more recent TypeScript versions, but type aliases for instance used to appear anonymously in error messages, https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#interfaces. Don't feel super strongly though so if you prefer reverting that change, will do.
I was thinking to use drawnFrame to get a measurement of how long each frame takes to render by comparing with a timestamp on enterFrame. To get a quick metric of how close we are to hitting the frame budget in an animation.
yes, I'd prefer to keep the PR scoped to the events and keep the types if you don't mind.
Regarding the drawnFrame, it makes sense.
Are you using the worker players?
In this case I'm trying to get a performance measurement of the regular Canvas renderer for an animation that's heavy on track mattes. So that animators can get an idea of how their animation performs without having to go into the browser's dev tools. Though on Safari at least measuring the difference between enterFrame
and drawnFrame
doesn't seem to capture this. It's around 5-6ms per frame, whereas painting seems to be the bottleneck:
So not sure how useful measuring drawnFrame
really is.
Would this be because the renderer just produces some instruction set for the canvas, and Safari computes the actual pixels in its compositing step?
I don't think it does, since you can add a breakpoint in any part of the code, and you'll see some paints already there, up to where the breakpoint stopped the execution.
It's not a fully reliable test, but I'm almost certain that those paints are synchronous to the execution of the code.
It would be different if you're using the worker, since Safari doesn't support OffscreeCanvas, so I'm collecting a set of instructions in the worker, and flushing them on the drawnFrame event to the main thread.
Dou you get different numbers on Chrome?
Interesting:
Browser | Time between drawn and enter |
FPS* |
---|---|---|
Safari | 5-6ms | 9 |
Chrome | 9-10ms | 55 |
* Measured by counting enterFrame
events per second.
The Chrome FPS makes sense to me; the screen refreshes at 120 Hz but the synchronous rendering takes >8ms. With some additional time for painting and other code there isn't too much of a gap between 10ms and 16ms for rendering at 60 FPS.
Safari seems to be doing a lot of work elsewhere (I'm running Lottie in React, but the page I'm testing with just has the Lottie player and no other code running).
Moving all this to the worker would free all that time budget. Even if it will still report 10ms, it's happening on a different thread, so the main thread is virtually not doing anything for Lottie.
But if that's not possible, large masks are expensive to render. The canvas renderer needs to allocate two extra buffers to make sure paintings happen in the right order.
Do you know if the svg numbers differ too much?
Yeah but the worker doesn't run in Safari currently (and even if the SVG worker would work, that probably doesn't make a noticeable difference with DOM changes still happening on the main thread).
On SVG this renders at around 45 FPS but becomes too slow in the context of the page we're using the animation. In either case, we've already discussed that the animators will look into less expensive ways to render the animation.
I suppose the main conclusion from this is that the drawn time - enter time
method isn't reliable for canvas rendering because it misses a significant portion of work done.
anyway, thanks for the PR. I'll merge it.
If you want, we can continue the conversation somewhere else.
Curious about why it doesn't work in Safari.
Are you referring to the SVG worker not working on Safari? Or to (measuring) the canvas performance. So that I have some info to create an issue where we could discuss further.
when you mentioned the worker doesn't run in Safari currently
Adds types for
addEventListener()
and related methods. Also documents thedrawnFrame
event.