Skip to content

Commit

Permalink
Improve getBlockEditingMode() and useAppender() performance (#51675)
Browse files Browse the repository at this point in the history
* Don't memoize getBlockEditingMode()

* useAppender(): Check block selection before other checks

* Don't return JSX from useSelect()
  • Loading branch information
noisysocks authored Jun 21, 2023
1 parent 7f4d64b commit a8ce505
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 57 deletions.
51 changes: 29 additions & 22 deletions packages/block-editor/src/components/block-list-appender/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function DefaultAppender( { rootClientId } ) {
}

function useAppender( rootClientId, CustomAppender ) {
const { hideInserter, isParentSelected } = useSelect(
const isVisible = useSelect(
( select ) => {
const {
getTemplateLock,
Expand All @@ -50,35 +50,42 @@ function useAppender( rootClientId, CustomAppender ) {
getBlockEditingMode,
} = unlock( select( blockEditorStore ) );

const selectedBlockClientId = getSelectedBlockClientId();
if ( CustomAppender === false ) {
return false;
}

return {
hideInserter:
!! getTemplateLock( rootClientId ) ||
getBlockEditingMode( rootClientId ) === 'disabled' ||
__unstableGetEditorMode() === 'zoom-out',
isParentSelected:
if ( ! CustomAppender ) {
const selectedBlockClientId = getSelectedBlockClientId();
const isParentSelected =
rootClientId === selectedBlockClientId ||
( ! rootClientId && ! selectedBlockClientId ),
};
( ! rootClientId && ! selectedBlockClientId );
if ( ! isParentSelected ) {
return false;
}
}

if (
getTemplateLock( rootClientId ) ||
getBlockEditingMode( rootClientId ) === 'disabled' ||
__unstableGetEditorMode() === 'zoom-out'
) {
return false;
}

return true;
},
[ rootClientId ]
[ rootClientId, CustomAppender ]
);

if ( hideInserter || CustomAppender === false ) {
if ( ! isVisible ) {
return null;
}

if ( CustomAppender ) {
// Prefer custom render prop if provided.
return <CustomAppender />;
}

if ( ! isParentSelected ) {
return null;
}

return <DefaultAppender rootClientId={ rootClientId } />;
return CustomAppender ? (
<CustomAppender />
) : (
<DefaultAppender rootClientId={ rootClientId } />
);
}

function BlockListAppender( {
Expand Down
60 changes: 25 additions & 35 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,41 +73,31 @@ export function getLastInsertedBlocksClientIds( state ) {
* @return {BlockEditingMode} The block editing mode. One of `'disabled'`,
* `'contentOnly'`, or `'default'`.
*/
export const getBlockEditingMode = createSelector(
( state, clientId = '' ) => {
if ( state.blockEditingModes.has( clientId ) ) {
return state.blockEditingModes.get( clientId );
}
if ( ! clientId ) {
return 'default';
}
const rootClientId = getBlockRootClientId( state, clientId );
const templateLock = getTemplateLock( state, rootClientId );
if ( templateLock === 'contentOnly' ) {
const name = getBlockName( state, clientId );
// TODO: Terrible hack! We're calling the global select() function
// here instead of using createRegistrySelector(). The problem with
// using createRegistrySelector() is that then the public
// block-editor selectors (e.g. canInsertBlockTypeUnmemoized) can't
// call this private block-editor selector due to a bug in
// @wordpress/data. See
// https://github.com/WordPress/gutenberg/pull/50985.
const isContent =
select( blocksStore ).__experimentalHasContentRoleAttribute(
name
);
return isContent ? 'contentOnly' : 'disabled';
}
const parentMode = getBlockEditingMode( state, rootClientId );
return parentMode === 'contentOnly' ? 'default' : parentMode;
},
( state ) => [
state.blockEditingModes,
state.blocks.parents,
state.settings.templateLock,
state.blockListSettings,
]
);
export function getBlockEditingMode( state, clientId = '' ) {
if ( state.blockEditingModes.has( clientId ) ) {
return state.blockEditingModes.get( clientId );
}
if ( ! clientId ) {
return 'default';
}
const rootClientId = getBlockRootClientId( state, clientId );
const templateLock = getTemplateLock( state, rootClientId );
if ( templateLock === 'contentOnly' ) {
const name = getBlockName( state, clientId );
// TODO: Terrible hack! We're calling the global select() function
// here instead of using createRegistrySelector(). The problem with
// using createRegistrySelector() is that then the public
// block-editor selectors (e.g. canInsertBlockTypeUnmemoized) can't
// call this private block-editor selector due to a bug in
// @wordpress/data. See
// https://github.com/WordPress/gutenberg/pull/50985.
const isContent =
select( blocksStore ).__experimentalHasContentRoleAttribute( name );
return isContent ? 'contentOnly' : 'disabled';
}
const parentMode = getBlockEditingMode( state, rootClientId );
return parentMode === 'contentOnly' ? 'default' : parentMode;
}

/**
* Returns true if the block with the given client ID and all of its descendants
Expand Down

0 comments on commit a8ce505

Please sign in to comment.