-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Lighter block DOM: put sibling inserter in popover #19456
Conversation
5b7678a
to
3fa6656
Compare
This branch seems to perform a lot better than
|
That speed boost is incredible! Let's get this in as fast as we can. Overall, this tests really well for me: I noticed two small issues. The first one you see at the end of that GIF, sometimes the sibling inserter plus seems to be lingering. It seems to work like this:
The other issue I'm unsure about, it could be a bad compile on my part, or a ghost of a previous branch, but I clicked a paragraph, then pressed Tab, and I got the following JS error:
Other than those two issues, this one feels great to me! |
@jasmussen Thanks a lot for testing! I'll work on fixes. |
I can't seem to reproduce the error. I click on a paragraph and press tab, but error. |
Probably just some local environment artifact on my side then. I've been jumping from fairly different branches. |
@jasmussen I think I fixed the lingering inserter. Is it better? For the other issue it might help to rebuild the files with |
@jasmussen Hm, that's strange I see this: |
Alright, I relocated home, and everything works as it should, suggesting it was my coworking space build system that was messy. The one final thing to look at is that the following should not be possible: That is — the sibling inserter should be available between all blocks when hovering, but never immediately before the selected block. Otherwise this can happen: That's the only remaining difference I can tell from this branch and master! |
@jasmussen Fixed that too now :) |
72cd331
to
25e92b0
Compare
25e92b0
to
4c12937
Compare
I think this is in a good shape now. The interaction is improved (more accurate hover targets), it clearly benefits performance, and there's a tabbable inserter just like before. Let's merge and iterate. |
😍 |
const [ inserterClientId, setInserterClientId ] = useState( null ); | ||
|
||
function onMouseMove( event ) { | ||
if ( event.target.className !== className ) { |
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.
What is this logic meant to be doing? It's quite unclear to me in reading this. A few inline comments or named utility functions could help clarify here.
FWIW, it raises some curiosity how reliable className
is here, whether that might hurt maintainability or interoperability (I know of at least a few Chrome extensions which apply classes to the live DOM, etc). Could be something where event.target.classList.contains
could prove more durable.
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.
Yeah, if we need to take into account outside changes to the class name, then checking with contains
is better. Even better would be to keep a list of all the reference check if it's included.
setIsInserterShown( true ); | ||
setInserterElement( element ); | ||
setInserterClientId( clientId ); |
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.
While it might not be too much an issue since setState
won't cause a render unless the state actually changes, I note (by placing a logpoint) that this gets called upwards of ~15 times every time a cursor moves within a sibling inserter. Is it something where (even if we don't strictly need to), we could abort the logic when determining that nothing needs to change?
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.
Would it make much difference, you think? I thought the only thing we'd avoid is an extra function call.
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.
Would it make much difference, you think? I thought the only thing we'd avoid is an extra function call.
It's hard to say. I'm not too sure what all React does internally to decide how to handle setState
. Depending if we could abort any earlier, it could be an opportunity to avoid reflow from one of the getBoundingClientRect
? I'm not sure of the implementation here to know whether that's even possible; I'd guess by the fact there are already some return;
that it's probably not?
It's interesting that we haven't noticed this before now, given that this PR is more than 2 months old. However it appears this PR regressed the behavior where a blue line appears after the selected line, when you hover a block in the toolbar. You can see it after the selected block here: After this PR, it's gone: @ellatrix do you think this is difficult to restore? |
I'll have a look. |
I don't know what happened here. I clearly recall working on this during the refactor so the line is preserved. I'll do some digging. |
Description
This results in a performance gain of 26% for typing. It also improves loading time. The big post we're testing loads 20% faster.
This PR moves the sibling inserter out of the block DOM. Currently it is rendered for every block on the page, selected or not, so it can be shown on hover. This PR takes a different approach: it looks at mouse movement between the block and then renders an inserter in the right place. Only one inserter is ever rendered.
In order for it to work for keyboard users, an inserter button is visually hidden in the toolbar, but shows when it receives focus. This is similar to other shortcuts in Gutenberg like the "open publish panel" button.
How has this been tested?
Screenshots
Types of changes
Checklist: