-
Notifications
You must be signed in to change notification settings - Fork 4.7k
useAvailableAlignments: avoid useSelect subscription when alignments array is empty #55449
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
|
Size Change: +8 B (0%) Total Size: 1.66 MB
ℹ️ View Unchanged
|
Mamaduka
left a comment
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.
Thank you, @jsnajdr!
The code looks good, and I couldn't spot regression in the alignment feature, and it should have a good e2e coverage (I think)
| // If `isNoneOnly` is true, we'll be returning early because there is | ||
| // nothing to filter on an empty array. We won't need the info from | ||
| // the `useSelect` but we must call it anyway because Rules of Hooks. | ||
| // So the callback returns early to avoid block editor subscription. | ||
| if ( isNoneOnly ) { | ||
| return [ false, false, false ]; | ||
| } |
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.
Hopefully, the comment will mitigate this odd return value 😄
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.
Yes, it bothers me that it looks so weird 🙂
On the other hand, this patch demonstrates a useSelect usage pattern that I think its quite neat and we could adopt it more widely: returning arrays instead of objects!
When writing:
const { themeSupportsLayout } = useSelect( ( select ) => ( { themeSupportsLayout: ... } ) );the themeSupportsLayout identifier is repeated twice, and constructing and destructuring the object is a bit unwieldy. Compare this to an array:
const [ themeSupportsLayout ] = useSelect( ( select ) => ( [ ... ] ) );That's much shorter and yet you don't lose any information. We're replacing the themeSupportsLayout with a 0 array index, basically. The field name doesn't matter because it's immediately destructured anyway.
Three optimizations related to the
useAvailableAlignmentshook and thealignattribute.There's an observation that if the
controlsarray passed touseAvailableAlignments( controls )is an[]empty array or[ 'none' ], the return value of the hook is going to be[]. The hook filters thecontrolsarray depending on what the theme and the parent layout says, but there's not much to do with an empty array.Therefore, in this case, we can make the
useSelectinsideuseAvailableAlignmentsinto a noop, so that it doesn't select fromcore/block-editorstore at all and doesn't create a subscription.The second observation is that sometimes we call
useAvailableAlignmentstwice. ThewithToolbarControlsHOC calls it the first time, and then theBlockAlignmentControlcomponent calls it the second time, on the result of the first call. We can remove thewithToolbarControlscall. It checks only for an empty array anyway, and theBlockAlignmentControlwill do the same check once again.The third optimization is in the
withDataAlignHOC. If thealignattribute isundefined, which it almost always is, the HOC does nothing at all. All the hook calls can be extracted into the helperBlockListBlockWithDataAligncomponent that is rendered only whenalignis defined.On a large post with 1400 blocks I was able to reduce the
core/block-editorsubscriptions by 2900, i.e., 2 per block.This improvement is a part of the program outlined in #54819.