-
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
Previews: avoid unneeded block selectors #60543
Changes from all commits
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 |
---|---|---|
|
@@ -562,38 +562,61 @@ function BlockListBlockProvider( props ) { | |
hasBlockSupport: _hasBlockSupport, | ||
getActiveBlockVariation, | ||
} = select( blocksStore ); | ||
const _isSelected = isBlockSelected( clientId ); | ||
const canRemove = canRemoveBlock( clientId, rootClientId ); | ||
const canMove = canMoveBlock( clientId, rootClientId ); | ||
const attributes = getBlockAttributes( clientId ); | ||
const { name: blockName, isValid } = blockWithoutAttributes; | ||
const blockType = getBlockType( blockName ); | ||
const { | ||
outlineMode, | ||
supportsLayout, | ||
__unstableIsPreviewMode: isPreviewMode, | ||
} = getSettings(); | ||
const hasLightBlockWrapper = blockType?.apiVersion > 1; | ||
const previewContext = { | ||
blockWithoutAttributes, | ||
name: blockName, | ||
attributes, | ||
isValid, | ||
themeSupportsLayout: supportsLayout, | ||
index: getBlockIndex( clientId ), | ||
isReusable: isReusableBlock( blockType ), | ||
className: hasLightBlockWrapper | ||
? attributes.className | ||
: undefined, | ||
defaultClassName: hasLightBlockWrapper | ||
? getBlockDefaultClassName( blockName ) | ||
: undefined, | ||
blockTitle: blockType?.title, | ||
}; | ||
|
||
// When in preview mode, we can avoid a lot of selection and | ||
// editing related selectors. | ||
if ( isPreviewMode ) { | ||
return previewContext; | ||
} | ||
|
||
const _isSelected = isBlockSelected( clientId ); | ||
const canRemove = canRemoveBlock( clientId, rootClientId ); | ||
const canMove = canMoveBlock( clientId, rootClientId ); | ||
const match = getActiveBlockVariation( blockName, attributes ); | ||
const { outlineMode, supportsLayout } = getSettings(); | ||
const isMultiSelected = isBlockMultiSelected( clientId ); | ||
const checkDeep = true; | ||
const isAncestorOfSelectedBlock = hasSelectedInnerBlock( | ||
clientId, | ||
checkDeep | ||
); | ||
const typing = isTyping(); | ||
const hasLightBlockWrapper = blockType?.apiVersion > 1; | ||
const movingClientId = hasBlockMovingClientId(); | ||
const blockEditingMode = getBlockEditingMode( clientId ); | ||
|
||
return { | ||
...previewContext, | ||
mode: getBlockMode( clientId ), | ||
isSelectionEnabled: isSelectionEnabled(), | ||
isLocked: !! getTemplateLock( rootClientId ), | ||
templateLock: getTemplateLock( clientId ), | ||
canRemove, | ||
canMove, | ||
blockWithoutAttributes, | ||
name: blockName, | ||
attributes, | ||
isValid, | ||
isSelected: _isSelected, | ||
themeSupportsLayout: supportsLayout, | ||
isTemporarilyEditingAsBlocks: | ||
__unstableGetTemporarilyEditingAsBlocks() === clientId, | ||
blockEditingMode, | ||
|
@@ -609,7 +632,6 @@ function BlockListBlockProvider( props ) { | |
'__experimentalExposeControlsToChildren', | ||
false | ||
) && hasSelectedInnerBlock( clientId ), | ||
index: getBlockIndex( clientId ), | ||
blockApiVersion: blockType?.apiVersion || 1, | ||
blockTitle: match?.title || blockType?.title, | ||
isSubtreeDisabled: | ||
|
@@ -629,7 +651,6 @@ function BlockListBlockProvider( props ) { | |
isMultiSelected && | ||
! __unstableIsFullySelected() && | ||
! __unstableSelectionHasUnmergeableBlock(), | ||
isReusable: isReusableBlock( blockType ), | ||
isDragging: isBlockBeingDragged( clientId ), | ||
hasChildSelected: isAncestorOfSelectedBlock, | ||
removeOutline: _isSelected && outlineMode && typing, | ||
|
@@ -644,28 +665,24 @@ function BlockListBlockProvider( props ) { | |
hasEditableOutline: | ||
blockEditingMode !== 'disabled' && | ||
getBlockEditingMode( rootClientId ) === 'disabled', | ||
className: hasLightBlockWrapper | ||
? attributes.className | ||
: undefined, | ||
defaultClassName: hasLightBlockWrapper | ||
? getBlockDefaultClassName( blockName ) | ||
: 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. I'm surprised this PR doesn't cause more issues. I feel like defensively, we should have default values for all of these keys in the 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. Why all? Only some end up as a public API. The rest is all internal context that we have control over. Fixed the public API ones in 04c36b8. 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. It was more about avoiding breakage. Like code base assuming some keys are defined... 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 can check all keys in a bit. Most of them are just used once in the block props hook, so it should be easy to double check. 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. Added one more ( |
||
}; | ||
}, | ||
[ clientId, rootClientId ] | ||
); | ||
|
||
const { | ||
mode, | ||
isSelectionEnabled, | ||
isLocked, | ||
canRemove, | ||
canMove, | ||
// Fill values that end up as a public API and may not be defined in | ||
// preview mode. | ||
mode = 'visual', | ||
isSelectionEnabled = false, | ||
isLocked = false, | ||
canRemove = false, | ||
canMove = false, | ||
blockWithoutAttributes, | ||
name, | ||
attributes, | ||
isValid, | ||
isSelected, | ||
isSelected = false, | ||
themeSupportsLayout, | ||
isTemporarilyEditingAsBlocks, | ||
blockEditingMode, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,6 +160,9 @@ export default function BlockList( settings ) { | |
); | ||
} | ||
|
||
const EMPTY_ARRAY = []; | ||
const EMPTY_SET = new Set(); | ||
|
||
function Items( { | ||
placeholder, | ||
rootClientId, | ||
|
@@ -175,6 +178,7 @@ function Items( { | |
useSelect( | ||
( select ) => { | ||
const { | ||
getSettings, | ||
getBlockOrder, | ||
getSelectedBlockClientId, | ||
getSelectedBlockClientIds, | ||
|
@@ -183,9 +187,20 @@ function Items( { | |
getBlockEditingMode, | ||
__unstableGetEditorMode, | ||
} = select( blockEditorStore ); | ||
|
||
const _order = getBlockOrder( rootClientId ); | ||
|
||
if ( getSettings().__unstableIsPreviewMode ) { | ||
return { | ||
order: _order, | ||
selectedBlocks: EMPTY_ARRAY, | ||
visibleBlocks: EMPTY_SET, | ||
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 one is interesting because it forces all blocks to be async right? This might have a good impact in terms of performance for the different interactions when previews are rendered. 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. (Idea for later) I actually wonder if we can't introduce a "priority" number in
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. They are already async because there is never any selection in previews. What would be priority 2? 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. The early return here is just to prevent the selectors from running, especially 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 mean a way to choose that some components even if async are higher priority than other async components. |
||
}; | ||
} | ||
|
||
const selectedBlockClientId = getSelectedBlockClientId(); | ||
return { | ||
order: getBlockOrder( rootClientId ), | ||
order: _order, | ||
selectedBlocks: getSelectedBlockClientIds(), | ||
visibleBlocks: __unstableGetVisibleBlocks(), | ||
shouldRenderAppender: | ||
|
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.
Btw, this makes me wonder what exactly it is below that is making the editable block slower. The pure amount of selectors, or are the particularly slow ones? One of the suspicious ones in
getBlockEditingMode
because it's recursive, and some of the other selectors make their own calls togetBlockEditingMode
.