perf: virtualize the notification list - #3319
Conversation
|
I've faced this freezing issue this week too; it might have been a recently introduced bug. |
|
In fact, the freezing was probably what you fixed in |
Shall we pull this out to a separate PR |
One repository can hold hundreds of notifications, so accounts, repository groups and rows are flattened into a single item sequence and windowed across group boundaries. Headers no longer own their rows, so collapse and exit-animation state moves up to the list and survives rows unmounting on scroll.
3586fe1 to
8a4f5bc
Compare
|
pulled the cache write fix out to #3320, that one is the mark-as-read freeze. for trying out LegendList, benched both on the same 1274-notification list: happy to swap, one catch: legend measures nothing in happy-dom, no layout and its ResizeObserver never fires, so the list renders zero rows there. the windowing tests would have to move to a real browser. ok with that? |
|
Thanks @fmguerreiro. I'd be leaning to keeping within the tanstack family for "simplicity". It's a positive improvement from current state |
|
@setchy there is no reason for us to stick with tanstack in this case just for the sake of it. It is an isolated package with zero relation to the rest. I think the numbers speak for themselves in terms of frame consistency. |
i'll let you have the final say on whichever path you'd like to go down. you know my thoughts ;) |
|
Alright, so I've done some local testing and got similar results to @fmguerreiro. I ran these on an M5 Macbook, so I throttled the CPU a bit, but older machines should definitely face this. So, on to the results. I tested both with 2,000 notifications in production Chrome, ran it 3 times and these are the averages:
The main reason I’d choose LegendList here is frame consistency under load, and I think that's mostly what we are targeting. I see no reason to make a performance improvement, without making sure that we've squeezed it all, and LegendList is known to be a legend of a package. As someone who has worked with React Native as well, it is a godsend. In any case, the implementation is also simpler since LegendList handles row positioning, measurement and scroll-container sizing. That removes code we would otherwise need to maintain ourselves. |
|
Sounds good to me :) |
Every row in the inbox mounts, so a large inbox paints tens of thousands of DOM nodes and re-renders all of them on each poll.
Virtualizes the list. Accounts, groups and rows flatten into one sequence, so one virtualizer windows across group boundaries. Rows unmount on scroll, so collapse and exit-animation state moved up to
NotificationList; headers split out asAccountHeaderandRepositoryHeader.Row heights are estimated, then corrected by measurement, so the scrollbar settles while scrolling.
The cache write fix that was the first commit here is now #3320.