-
Notifications
You must be signed in to change notification settings - Fork 4.6k
List View: make sure sidebar component updates after blocks are added, removed or inserted #34477
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
Conversation
… removed or inserted
| case 'REMOVE_BLOCKS': | ||
| case 'REPLACE_BLOCKS': | ||
| case 'RESET_BLOCKS': | ||
| return uuid(); |
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.
Note that we don't necessarily need to use a uuid, it just seemed convenient. I'm open to whatever naming changes folks prefer too.
|
Size Change: +665 B (0%) Total Size: 1.04 MB
ℹ️ View Unchanged
|
|
I know @youknowriad has been making some changes to the block editor store of late, so might have some insights into what can be done to improve List View. I noticed the work in #34241 builds a block tree in the reducer, so I'd be curious if List View could now use that instead of assembling a tree in the selector. It might be possible to drive the whole of list view from that data, which should avoid those rendering glitches. (edit: although having said that, I think the code currently tries to avoid an entire re-render when only attributes change, might have to test if that's still possible).
Just noticed that's looks like that's only for the site editor. From what I understand ListView already uses AsyncModeProvider to help already with typing performance. |
|
Do we already use |
|
Yep, |
|
@talldan that's probably the reason the updates seem to happen a bit later after addition, removals... is because it's async rendered entirely, maybe if we try sync rendering around the visible items it will be better. |
ListView when used in the sidebar is a little different in that the backing tree really only needs to know when Happy to try out alternatives, but I suspect If we recalculate the backing tree on every block update, all child items will re-render. Ideally we should aim to not re-render the ListView component while typing (which will trigger all child items to update). This is necessary if we're interested in using framer motion for dragging. Without it or some way to limit the number of child blocks drawn (eg windowing), performance will be a blocker for that one. #34022 Did folks want to spin up an alternative PR? I'd be happy to help profile/test it. |
@youknowriad I tested removing the
Thinking about it some more, the problem isn't that the individual block data is slow to update, its the other way around, instead it's the data at the root of ListView that's wrapped in Perhaps we can be a little bit more selective about what data is used inside and outside of
Yep, I realised that and updated the comment. I still think there might be a better approach than using a UUID as that's somewhat similar to the cache keys that were just removed.
It does need to update at some point, some blocks use block attribute for the name shown in List View (Navigation Link, Template Parts), and this can be changed by typing. |
|
Ok, I did manage to iterate on #34519 and get it working. Once I typed out the above comment things became a bit clearer. |
|
Closing this one in favor of #34519. Thanks for taking a look @talldan!
Child components appear to update just fine when backed by global state, but I'm fine with leaving the potential memo for another PR. ( I really only need the performance boost if we switch over to framer motion for drag/animation). You can see this typing updating list view children in the after video at around the 40 second mark. |
Fixes #34310
The backing block tree for ListView (
clientIdsTree) is sometimes slow to be recalculated when blocks are removed or added. This can make a removal of a parent block appear to be slow, since the child items are updating before the backed tree.Changes in this PR add a small reducer that updates a string value whenever blocks are added, removed or inserted. (New clientIds vs block props changing.)
I also memo'd ListViewSidebar to avoid unnecessary re-renders while typing. It makes more sense to memo a larger component, since the default behavior in react is that any parent render will trigger it's child render (regardless of if props have changed or not).
Before:
slow.remove.mp4
After:
after.mp4
Testing Instructions: