Skip to content

Commit

Permalink
Reduce number of List View re-renders while typing (#51518)
Browse files Browse the repository at this point in the history
* Add getClientIdsTreeWithBlockEditingMode()

* Rename getClientIdsTreeWithBlockEditingMode -> getListViewClientIdsTree
  • Loading branch information
noisysocks authored Jun 19, 2023
1 parent a67d478 commit 7f2ea04
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,14 @@ export default function useListViewClientIds( { blocks, rootClientId } ) {
const {
getDraggedBlockClientIds,
getSelectedBlockClientIds,
__unstableGetClientIdsTree,
getBlockEditingMode,
getListViewClientIdsTree,
} = unlock( select( blockEditorStore ) );

const removeDisabledBlocks = ( tree ) => {
return tree.flatMap( ( { clientId, innerBlocks, ...rest } ) => {
if ( getBlockEditingMode( clientId ) === 'disabled' ) {
return removeDisabledBlocks( innerBlocks );
}
return [
{
clientId,
innerBlocks: removeDisabledBlocks( innerBlocks ),
...rest,
},
];
} );
};

return {
selectedClientIds: getSelectedBlockClientIds(),
draggedClientIds: getDraggedBlockClientIds(),
clientIdsTree: removeDisabledBlocks(
blocks ?? __unstableGetClientIdsTree( rootClientId )
),
clientIdsTree:
blocks ?? getListViewClientIdsTree( rootClientId ),
};
},
[ blocks, rootClientId ]
Expand Down
34 changes: 34 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,37 @@ export const isBlockSubtreeDisabled = createSelector(
},
( state ) => [ state.blockEditingModes, state.blocks.parents ]
);

/**
* Returns a tree of block objects with only clientID and innerBlocks set.
* Blocks with a 'disabled' editing mode are not included.
*
* @param {Object} state Global application state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Object[]} Tree of block objects with only clientID and innerBlocks set.
*/
export const getListViewClientIdsTree = createSelector(
( state, rootClientId = '' ) => {
return getBlockOrder( state, rootClientId ).flatMap( ( clientId ) => {
if ( getBlockEditingMode( state, clientId ) !== 'disabled' ) {
return [
{
clientId,
innerBlocks: getListViewClientIdsTree(
state,
clientId
),
},
];
}
return getListViewClientIdsTree( state, clientId );
} );
},
( state ) => [
state.blocks.order,
state.blockEditingModes,
state.settings.templateLock,
state.blockListSettings,
]
);
35 changes: 28 additions & 7 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,27 @@ export function getBlocks( state, rootClientId ) {
* Returns a stripped down block object containing only its client ID,
* and its inner blocks' client IDs.
*
* @deprecated
*
* @param {Object} state Editor state.
* @param {string} clientId Client ID of the block to get.
*
* @return {Object} Client IDs of the post blocks.
*/
export const __unstableGetClientIdWithClientIdsTree = createSelector(
( state, clientId ) => ( {
clientId,
innerBlocks: __unstableGetClientIdsTree( state, clientId ),
} ),
( state, clientId ) => {
deprecated(
"wp.data.select( 'core/block-editor' ).__unstableGetClientIdWithClientIdsTree",
{
since: '6.3',
version: '6.5',
}
);
return {
clientId,
innerBlocks: __unstableGetClientIdsTree( state, clientId ),
};
},
( state ) => [ state.blocks.order ]
);

Expand All @@ -205,16 +216,26 @@ export const __unstableGetClientIdWithClientIdsTree = createSelector(
* given root, consisting of stripped down block objects containing only
* their client IDs, and their inner blocks' client IDs.
*
* @deprecated
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Object[]} Client IDs of the post blocks.
*/
export const __unstableGetClientIdsTree = createSelector(
( state, rootClientId = '' ) =>
getBlockOrder( state, rootClientId ).map( ( clientId ) =>
( state, rootClientId = '' ) => {
deprecated(
"wp.data.select( 'core/block-editor' ).__unstableGetClientIdsTree",
{
since: '6.3',
version: '6.5',
}
);
return getBlockOrder( state, rootClientId ).map( ( clientId ) =>
__unstableGetClientIdWithClientIdsTree( state, clientId )
),
);
},
( state ) => [ state.blocks.order ]
);

Expand Down
174 changes: 173 additions & 1 deletion packages/block-editor/src/store/test/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getLastInsertedBlocksClientIds,
getBlockEditingMode,
isBlockSubtreeDisabled,
getListViewClientIdsTree,
} from '../private-selectors';

jest.mock( '@wordpress/data/src/select', () => ( {
Expand Down Expand Up @@ -74,7 +75,13 @@ describe( 'private selectors', () => {
[ 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c', {} ], // | | Paragraph
] ),
order: new Map( [
[ '', [ '6cf70164-9097-4460-bcbf-200560546988' ] ],
[
'',
[
'6cf70164-9097-4460-bcbf-200560546988',
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
],
],
[ '6cf70164-9097-4460-bcbf-200560546988', [] ],
[
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
Expand Down Expand Up @@ -382,4 +389,169 @@ describe( 'private selectors', () => {
} );
} );
} );

describe( 'getListViewClientIdsTree', () => {
const baseState = {
settings: {},
blocks: {
byClientId: new Map( [
[ '6cf70164-9097-4460-bcbf-200560546988', {} ], // Header
[ 'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337', {} ], // Group
[ 'b26fc763-417d-4f01-b81c-2ec61e14a972', {} ], // | Post Title
[ '9b9c5c3f-2e46-4f02-9e14-9fe9515b958f', {} ], // | Post Content
[ 'b3247f75-fd94-4fef-97f9-5bfd162cc416', {} ], // | | Paragraph
[ 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c', {} ], // | | Paragraph
] ),
order: new Map( [
[
'',
[
'6cf70164-9097-4460-bcbf-200560546988',
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
],
],
[ '6cf70164-9097-4460-bcbf-200560546988', [] ],
[
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
[
'b26fc763-417d-4f01-b81c-2ec61e14a972',
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
],
],
[ 'b26fc763-417d-4f01-b81c-2ec61e14a972', [] ],
[
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
[
'b3247f75-fd94-4fef-97f9-5bfd162cc416',
'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
],
],
[ 'b3247f75-fd94-4fef-97f9-5bfd162cc416', [] ],
[ 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c', [] ],
] ),
parents: new Map( [
[ '6cf70164-9097-4460-bcbf-200560546988', '' ],
[ 'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337', '' ],
[
'b26fc763-417d-4f01-b81c-2ec61e14a972',
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
],
[
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
],
[
'b3247f75-fd94-4fef-97f9-5bfd162cc416',
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
],
[
'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
],
] ),
},
blockListSettings: {
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337': {},
'9b9c5c3f-2e46-4f02-9e14-9fe9515b958f': {},
},
};

it( 'should return tree containing only clientId and innerBlocks', () => {
const state = {
...baseState,
blockEditingModes: new Map( [] ),
};
expect( getListViewClientIdsTree( state ) ).toEqual( [
{
clientId: '6cf70164-9097-4460-bcbf-200560546988',
innerBlocks: [],
},
{
clientId: 'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337',
innerBlocks: [
{
clientId: 'b26fc763-417d-4f01-b81c-2ec61e14a972',
innerBlocks: [],
},
{
clientId: '9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
innerBlocks: [
{
clientId:
'b3247f75-fd94-4fef-97f9-5bfd162cc416',
innerBlocks: [],
},
{
clientId:
'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
innerBlocks: [],
},
],
},
],
},
] );
} );

it( 'should return a subtree when rootBlockClientId is given', () => {
const state = {
...baseState,
blockEditingModes: new Map( [] ),
};
expect(
getListViewClientIdsTree(
state,
'ef45d5fd-5234-4fd5-ac4f-c3736c7f9337'
)
).toEqual( [
{
clientId: 'b26fc763-417d-4f01-b81c-2ec61e14a972',
innerBlocks: [],
},
{
clientId: '9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
innerBlocks: [
{
clientId: 'b3247f75-fd94-4fef-97f9-5bfd162cc416',
innerBlocks: [],
},
{
clientId: 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
innerBlocks: [],
},
],
},
] );
} );

it( 'should filter out disabled blocks', () => {
const state = {
...baseState,
blockEditingModes: new Map( [
[ '', 'disabled' ],
[ 'b26fc763-417d-4f01-b81c-2ec61e14a972', 'contentOnly' ],
[ '9b9c5c3f-2e46-4f02-9e14-9fe9515b958f', 'contentOnly' ],
] ),
};
expect( getListViewClientIdsTree( state ) ).toEqual( [
{
clientId: 'b26fc763-417d-4f01-b81c-2ec61e14a972',
innerBlocks: [],
},
{
clientId: '9b9c5c3f-2e46-4f02-9e14-9fe9515b958f',
innerBlocks: [
{
clientId: 'b3247f75-fd94-4fef-97f9-5bfd162cc416',
innerBlocks: [],
},
{
clientId: 'e178812d-ce5e-48c7-a945-8ae4ffcbbb7c',
innerBlocks: [],
},
],
},
] );
} );
} );
} );
1 change: 1 addition & 0 deletions packages/block-editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4734,6 +4734,7 @@ describe( '__unstableGetClientIdWithClientIdsTree', () => {
{ clientId: 'baz', innerBlocks: [] },
],
} );
expect( console ).toHaveWarned();
} );
} );
describe( '__unstableGetClientIdsTree', () => {
Expand Down

1 comment on commit 7f2ea04

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 7f2ea04.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5307616873
📝 Reported issues:

Please sign in to comment.