Improve Inserter block hover performance#26348
Conversation
|
Size Change: +112 B (0%) Total Size: 1.3 MB
ℹ️ View Unchanged
|
Addison-Stavlo
left a comment
There was a problem hiding this comment.
In testing locally without throttling im not really noticing any difference in use. However, inspecting with Chrome performance tools I see some things like the mouseOut between each item going from ~28ms down to ~5ms, so it seems to be making a difference!
I notice we are memo-ing a lot of things here. All in all we definitely seem to be getting a better end result, but I can't help but wonder if any of these more basic items aren't worth the overhead of the memo. 🤔
| onHover={ onHover } | ||
| filterValue={ filterValue } | ||
| /> | ||
| const getCurrentTab = useCallback( |
There was a problem hiding this comment.
Ooo. I really like this implementation. Memoizing the .map() callback for iterating renders :D
ItsJonQ
left a comment
There was a problem hiding this comment.
🚀 from me! Thanks @david-szabo97 for taking this on :).
I took it for a spin. Both the Block Inserter (top left) and the inline Quick inserter continue to work as normal.
I opened up React's dev tools to check for re-renders. They're definitely more controlled this time, as demonstrated in your GIF.
The memoization implementations look good to me!
We're only scratching the surface with this one. But it's a wonderful start ⭐
|
thanks for your work here, the inserter was not really optimized like ever. I share what @Addison-Stavlo shared above. Ideally, we'd try to understand exactly the bottleneck. That said, is there a way to add a measure to the performance tests to measure the impacts on actual numbers? Avoid rerenders doesn't always mean better performance. |
Your best bet is probably using Puppeteer to automate a sequence of steps, and measuring how long the click events take, similar to what you're doing for editor performance. |
8893488 to
0bb44f8
Compare
|
Merged a PR which adds inserter perf measurements. Hover seems to be 30-40% faster in this PR. |
youknowriad
left a comment
There was a problem hiding this comment.
Good timing improvements. I do believe it's better if we identify precisely what components/props need to be memoized instead of just memorizing everything. We may have particular components that are not well written and memorizing hides the issue.
| } | ||
|
|
||
| export default BlockTypesList; | ||
| export default memo( BlockTypesList ); |
There was a problem hiding this comment.
Anything in particular that requires this memo call?
| } | ||
|
|
||
| export default InserterListItem; | ||
| export default memo( InserterListItem ); |
There was a problem hiding this comment.
I can see that being useful as we don't want to "rerender all items" when just one of them changes.
packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
Show resolved
Hide resolved
packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
Outdated
Show resolved
Hide resolved
| { __( 'A tip for using the block editor' ) } | ||
| </VisuallyHidden> | ||
| <Tips /> | ||
| const blocksTab = useMemo( |
There was a problem hiding this comment.
I believe memoizing elements or render props is useless
There was a problem hiding this comment.
These elements are used inside a render function. In this case, the render function will return a totally new element every time it's called - which results in all items being rerendered. If we are using memorization then it will reuse the same element every time.
There was a problem hiding this comment.
React already does diffing when it comes to element, so I'm not sure that's necessary. Also since this is more top level, it's less necessary than memorizing leafs. Do you think we can try removing the memoization and see what impact it has on the numbers?
There was a problem hiding this comment.
Before:
│ inserterHover │ '38.89 ms' │ '69.18 ms' │
│ minInserterHover │ '35.32 ms' │ '64.11 ms' │
│ maxInserterHover │ '48.13 ms' │ '76.42 ms' │
There was a problem hiding this comment.
Interesting, so all the performance gain is coming from the memoization of the tabs?
There was a problem hiding this comment.
If you boot up React profiler and enable "highlight updates" then you can clearly see all the items are rerendering when the memo is removed.
Since the passed children is a function, it behaves differently than just a simple element. That's why it's creating a whole new tree without on every render without the memo.
There was a problem hiding this comment.
Ok, I think I still need to understand why the top component is rerendering at all but let's bring back the memorization for now. Thanks for your work and explorations. Highly appreciated and sorry for the back and forth.
There was a problem hiding this comment.
No worries! My thanks for going on with this!
|
Would you mind rebasing the PR one more time, the drag and drop that just landed in master (not sure if included here yet) could impact the numbers. |
This reverts commit 2321b74.
…r-hover-performance
…r-hover-performance

Description
When moving our mouse over the blocks in the inserter it doesn't feel smooth. These changes aim to make it a smoother experience by avoiding unnecessary rerenders.
How has this been tested?
yarn devScreenshots
Profiling and GIFs were done in the Site Editor. Both the performance gains are both the same for Post and Site editor since they are using the same shared components where I made the changes.
Chrome performance profiler (no throttling)
React performance profiler (no throttling)
Highlighting rerendered components
Types of changes
Performance
Checklist: