-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Performance: optimize the usage of getBlockIndex #13067
Changes from all commits
d1aecb1
94d8884
8c706e9
3de6e0c
08b8b30
2d984c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,8 +55,9 @@ class BlockDropZone extends Component { | |
} | ||
|
||
getInsertIndex( position ) { | ||
const { index } = this.props; | ||
if ( index !== undefined ) { | ||
const { clientId, rootClientId, getBlockIndex } = this.props; | ||
if ( clientId !== undefined ) { | ||
const index = getBlockIndex( clientId, rootClientId ); | ||
return position.y === 'top' ? index : index + 1; | ||
} | ||
} | ||
|
@@ -83,7 +84,7 @@ class BlockDropZone extends Component { | |
} | ||
|
||
onDrop( event, position ) { | ||
const { rootClientId: dstRootClientId, clientId: dstClientId, index: dstIndex, getClientIdsOfDescendants } = this.props; | ||
const { rootClientId: dstRootClientId, clientId: dstClientId, getClientIdsOfDescendants, getBlockIndex } = this.props; | ||
const { srcRootClientId, srcClientId, srcIndex, type } = parseDropEvent( event ); | ||
|
||
const isBlockDropType = ( dropType ) => dropType === 'block'; | ||
|
@@ -101,6 +102,7 @@ class BlockDropZone extends Component { | |
return; | ||
} | ||
|
||
const dstIndex = dstClientId ? getBlockIndex( dstClientId, dstRootClientId ) : undefined; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What |
||
const positionIndex = this.getInsertIndex( position ); | ||
// If the block is kept at the same level and moved downwards, | ||
// subtract to account for blocks shifting upward to occupy its old position. | ||
|
@@ -154,10 +156,11 @@ export default compose( | |
}; | ||
} ), | ||
withSelect( ( select, { rootClientId } ) => { | ||
const { getClientIdsOfDescendants, getTemplateLock } = select( 'core/editor' ); | ||
const { getClientIdsOfDescendants, getTemplateLock, getBlockIndex } = select( 'core/editor' ); | ||
return { | ||
isLocked: !! getTemplateLock( rootClientId ), | ||
getClientIdsOfDescendants, | ||
getBlockIndex, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume that it isn't something we can handle using |
||
}; | ||
} ), | ||
withFilters( 'editor.BlockDropZone' ) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ function BlockListAppender( { | |
disabled={ disabled } | ||
/> | ||
) } | ||
isAppender | ||
/> | ||
</div> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,7 @@ import { KeyboardShortcuts, withFilters } from '@wordpress/components'; | |
import { __, sprintf } from '@wordpress/i18n'; | ||
import { withDispatch, withSelect } from '@wordpress/data'; | ||
import { withViewportMatch } from '@wordpress/viewport'; | ||
import { compose } from '@wordpress/compose'; | ||
import { compose, pure } from '@wordpress/compose'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -59,7 +59,6 @@ export class BlockListBlock extends Component { | |
this.maybeHover = this.maybeHover.bind( this ); | ||
this.forceFocusedContextualToolbar = this.forceFocusedContextualToolbar.bind( this ); | ||
this.hideHoverEffects = this.hideHoverEffects.bind( this ); | ||
this.insertBlocksAfter = this.insertBlocksAfter.bind( this ); | ||
this.onFocus = this.onFocus.bind( this ); | ||
this.preventDrag = this.preventDrag.bind( this ); | ||
this.onPointerDown = this.onPointerDown.bind( this ); | ||
|
@@ -233,10 +232,6 @@ export class BlockListBlock extends Component { | |
} | ||
} | ||
|
||
insertBlocksAfter( blocks ) { | ||
this.props.onInsertBlocks( blocks, this.props.order + 1 ); | ||
} | ||
|
||
/** | ||
* Marks the block as selected when focused and not already selected. This | ||
* specifically handles the case where block does not set focus on its own | ||
|
@@ -361,7 +356,6 @@ export class BlockListBlock extends Component { | |
<HoverArea container={ this.wrapperNode }> | ||
{ ( { hoverArea } ) => { | ||
const { | ||
order, | ||
mode, | ||
isFocusMode, | ||
hasFixedToolbar, | ||
|
@@ -397,11 +391,9 @@ export class BlockListBlock extends Component { | |
// Empty paragraph blocks should always show up as unselected. | ||
const showEmptyBlockSideInserter = | ||
( isSelected || isHovered ) && isEmptyDefaultBlock && isValid; | ||
const showSideInserter = | ||
( isSelected || isHovered ) && isEmptyDefaultBlock; | ||
const shouldAppearSelected = | ||
! isFocusMode && | ||
! showSideInserter && | ||
! showEmptyBlockSideInserter && | ||
isSelected && | ||
! isTypingWithinBlock; | ||
const shouldAppearHovered = | ||
|
@@ -420,7 +412,7 @@ export class BlockListBlock extends Component { | |
! isFocusMode && isHovered && ! isEmptyDefaultBlock; | ||
const shouldShowContextualToolbar = | ||
! hasFixedToolbar && | ||
! showSideInserter && | ||
! showEmptyBlockSideInserter && | ||
( ( isSelected && | ||
( ! isTypingWithinBlock || isCaretWithinFormattedText ) ) || | ||
isFirstMultiSelected ); | ||
|
@@ -474,7 +466,7 @@ export class BlockListBlock extends Component { | |
isSelected={ isSelected } | ||
attributes={ attributes } | ||
setAttributes={ this.setAttributes } | ||
insertBlocksAfter={ isLocked ? undefined : this.insertBlocksAfter } | ||
insertBlocksAfter={ isLocked ? undefined : this.props.onInsertBlocksAfter } | ||
onReplace={ isLocked ? undefined : onReplace } | ||
mergeBlocks={ isLocked ? undefined : this.props.onMerge } | ||
clientId={ clientId } | ||
|
@@ -521,7 +513,6 @@ export class BlockListBlock extends Component { | |
/> | ||
) } | ||
<BlockDropZone | ||
index={ order } | ||
clientId={ clientId } | ||
rootClientId={ rootClientId } | ||
/> | ||
|
@@ -612,6 +603,8 @@ export class BlockListBlock extends Component { | |
<Inserter | ||
position="top right" | ||
onToggle={ this.selectOnOpen } | ||
rootClientId={ rootClientId } | ||
clientId={ clientId } | ||
/> | ||
</div> | ||
</Fragment> | ||
|
@@ -634,7 +627,6 @@ const applyWithSelect = withSelect( | |
isFirstMultiSelectedBlock, | ||
isTyping, | ||
isCaretWithinFormattedText, | ||
getBlockIndex, | ||
getBlockMode, | ||
isSelectionEnabled, | ||
getSelectedBlocksInitialCaretPosition, | ||
|
@@ -663,10 +655,9 @@ const applyWithSelect = withSelect( | |
isTypingWithinBlock: | ||
( isSelected || isParentOfSelectedBlock ) && isTyping(), | ||
isCaretWithinFormattedText: isCaretWithinFormattedText(), | ||
order: getBlockIndex( clientId, rootClientId ), | ||
mode: getBlockMode( clientId ), | ||
isSelectionEnabled: isSelectionEnabled(), | ||
initialPosition: getSelectedBlocksInitialCaretPosition(), | ||
initialPosition: isSelected ? getSelectedBlocksInitialCaretPosition() : null, | ||
isEmptyDefaultBlock: | ||
name && isUnmodifiedDefaultBlock( { name, attributes } ), | ||
isMovable: 'all' !== templateLock, | ||
|
@@ -715,8 +706,20 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => { | |
insertBlocks( blocks, index, rootClientId ); | ||
}, | ||
onInsertDefaultBlockAfter() { | ||
const { order, rootClientId } = ownProps; | ||
insertDefaultBlock( {}, rootClientId, order + 1 ); | ||
const { clientId, rootClientId } = ownProps; | ||
const { | ||
getBlockIndex, | ||
} = select( 'core/editor' ); | ||
const index = getBlockIndex( clientId, rootClientId ); | ||
insertDefaultBlock( {}, rootClientId, index + 1 ); | ||
}, | ||
onInsertBlocksAfter( blocks ) { | ||
const { clientId, rootClientId } = ownProps; | ||
const { | ||
getBlockIndex, | ||
} = select( 'core/editor' ); | ||
const index = getBlockIndex( clientId, rootClientId ); | ||
insertBlocks( blocks, index + 1, rootClientId ); | ||
}, | ||
onRemove( clientId ) { | ||
removeBlock( clientId ); | ||
|
@@ -764,6 +767,7 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => { | |
} ); | ||
|
||
export default compose( | ||
pure, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is useful to avoid rerendering all the blocks when we add/remove a block in the block list (parent component). I was also tempted to replace it with |
||
withViewportMatch( { isLargeViewport: 'medium' } ), | ||
applyWithSelect, | ||
applyWithDispatch, | ||
|
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.
@aduth - I don't see it on the list in #12890.
Anyways, I'm happy seeing that
select
is helping us to improve performance. We still didn't discover any downsides which is encouraging to do more refactoring like this.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.
I think it was missed because I was explicitly looking for
withDispatch( ( dispatch, ownProps )
orwithDispatch( ( dispatch, {
. We apparently have more variation 😬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.
This is the only occurrence of the second argument being named as "props" for
withDispatch
, and best I could tell (by a regular expression search ofwithDispatch\( \( dispatch, [^{o]
) there are no other variations.