perf: improve rendering performance by throttling updates to 60fps#2977
perf: improve rendering performance by throttling updates to 60fps#2977MitjaBezensek merged 40 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Ignored Deployment
|
0704d75 to
ae946d5
Compare
b506ab8 to
c545659
Compare
|
Anything left on this one? |
|
Yes, it's now ready for review 😄 |
ds300
left a comment
There was a problem hiding this comment.
Looks great! I wonder if we can simplify the state chart bits by supporting an onThrottledMouseMove callback method that does the dirty checking and uses the tick under the hood, to simplify this kind of workflow that you've had to reproduce in a bunch of places? Might be more trouble than it's worth and can definitely be done separately from this PR so not blocking in any way.
packages/utils/src/lib/throttle.ts
Outdated
| const tick = () => { | ||
| const queue = fpsQueue.splice(0, fpsQueue.length) | ||
| for (const fn of queue) { | ||
| fn() | ||
| } | ||
| } | ||
|
|
||
| function fps() { |
There was a problem hiding this comment.
extremely nonblocking nitpick:
I found the naming here a little odd. I'd personally change tick to flush and change fps to tick. For me a tick is some kind of regularly scheduled event for managing asynchronous execution of other things, which is kinda what your fps function is doing.
I dunno, could just be me though 🤷🏼
There was a problem hiding this comment.
Proposed names definitely make more sense to me, thanks for the suggestion.
| * @returns | ||
| * @internal | ||
| */ | ||
| export function throttleToNextFrame(fn: () => void) { |
There was a problem hiding this comment.
yes!
throttleToNextFrame and fpsThrottle is a much less confusing naming scheme than what we had before 🙌🏼
| if (this.isDirty) { | ||
| this.isDirty = false | ||
| this.updateScribbleSelection(true) | ||
| } |
There was a problem hiding this comment.
I wonder whether we should run these in onComplete too? To get the absolute final positions. Probably not gonna be noticeable unless the frame rate gets quite low tbh.
This PR does a few things to help with performance:
useValueanduseStateTrackinghooks.pointerMove) in state nodes. This means we batch multiple inputs and only apply them at most 60 times per second.We had to adjust our own tests to pass after this change so I marked this as major as it might require the users of the library to do the same.
Few observations:
Few tests below. Used 6x slowdown for these.
Resizing
Before
CleanShot.2024-02-28.at.09.52.32.mp4
After
CleanShot.2024-02-28.at.09.53.22.mp4
Drawing
Comparison is not 100% fair, we don't store the intermediate inputs right now. That said, tick should still only produce once update so I do think we can get a sense of the differences.
Before
CleanShot.2024-02-28.at.09.54.55.mp4
After
CleanShot.2024-02-28.at.09.54.22.mp4
Change type
improvementTest plan
Release notes