Skip to content

Commit

Permalink
Perf: batch block list settings in single action (WordPress#61329)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <[email protected]>
Co-authored-by: jsnajdr <[email protected]>
  • Loading branch information
3 people authored May 21, 2024
1 parent 187bcb0 commit 8bd3d46
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 33 deletions.
4 changes: 2 additions & 2 deletions docs/reference-guides/data/data-core-block-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -1841,11 +1841,11 @@ _Returns_

### updateBlockListSettings

Action that changes the nested settings of a given block.
Action that changes the nested settings of the given block(s).

_Parameters_

- _clientId_ `string`: Client ID of the block whose nested setting are being received.
- _clientId_ `string | SettingsByClientId`: Client ID of the block whose nested setting are being received, or object of settings by client ID.
- _settings_ `Object`: Object with the new settings for the nested block.

_Returns_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { useLayoutEffect, useMemo, useState } from '@wordpress/element';
import { useDispatch, useRegistry } from '@wordpress/data';
import { useRegistry } from '@wordpress/data';
import deprecated from '@wordpress/deprecated';
import isShallowEqual from '@wordpress/is-shallow-equal';

Expand Down Expand Up @@ -69,7 +69,6 @@ export default function useNestedSettingsUpdate(
// Instead of adding a useSelect mapping here, please add to the useSelect
// mapping in InnerBlocks! Every subscription impacts performance.

const { updateBlockListSettings } = useDispatch( blockEditorStore );
const registry = useRegistry();

// Implementors often pass a new array on every render,
Expand Down Expand Up @@ -155,21 +154,16 @@ export default function useNestedSettingsUpdate(
// we batch all the updatedBlockListSettings in a single "data" batch
// which results in a single re-render.
if ( ! pendingSettingsUpdates.get( registry ) ) {
pendingSettingsUpdates.set( registry, [] );
pendingSettingsUpdates.set( registry, {} );
}
pendingSettingsUpdates
.get( registry )
.push( [ clientId, newSettings ] );
pendingSettingsUpdates.get( registry )[ clientId ] = newSettings;
window.queueMicrotask( () => {
if ( pendingSettingsUpdates.get( registry )?.length ) {
registry.batch( () => {
pendingSettingsUpdates
.get( registry )
.forEach( ( args ) => {
updateBlockListSettings( ...args );
} );
pendingSettingsUpdates.set( registry, [] );
} );
const settings = pendingSettingsUpdates.get( registry );
if ( Object.keys( settings ).length ) {
const { updateBlockListSettings } =
registry.dispatch( blockEditorStore );
updateBlockListSettings( settings );
pendingSettingsUpdates.set( registry, {} );
}
} );
}, [
Expand All @@ -183,7 +177,6 @@ export default function useNestedSettingsUpdate(
__experimentalDirectInsert,
captureToolbars,
orientation,
updateBlockListSettings,
layout,
registry,
] );
Expand Down
15 changes: 11 additions & 4 deletions packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1506,11 +1506,18 @@ export const insertDefaultBlock =
};

/**
* Action that changes the nested settings of a given block.
* @typedef {Object< string, Object >} SettingsByClientId
*/

/**
* Action that changes the nested settings of the given block(s).
*
* @param {string} clientId Client ID of the block whose nested setting are
* being received.
* @param {Object} settings Object with the new settings for the nested block.
* @param {string | SettingsByClientId} clientId Client ID of the block whose
* nested setting are being
* received, or object of settings
* by client ID.
* @param {Object} settings Object with the new settings
* for the nested block.
*
* @return {Object} Action object
*/
Expand Down
35 changes: 24 additions & 11 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1750,24 +1750,37 @@ export const blockListSettings = ( state = {}, action ) => {
);
}
case 'UPDATE_BLOCK_LIST_SETTINGS': {
const { clientId } = action;
if ( ! action.settings ) {
if ( state.hasOwnProperty( clientId ) ) {
const { [ clientId ]: removedBlock, ...restBlocks } = state;
return restBlocks;
const updates =
typeof action.clientId === 'string'
? { [ action.clientId ]: action.settings }
: action.clientId;

// Remove settings that are the same as the current state.
for ( const clientId in updates ) {
if ( ! updates[ clientId ] ) {
if ( ! state[ clientId ] ) {
delete updates[ clientId ];
}
} else if (
fastDeepEqual( state[ clientId ], updates[ clientId ] )
) {
delete updates[ clientId ];
}
}

if ( Object.keys( updates ).length === 0 ) {
return state;
}

if ( fastDeepEqual( state[ clientId ], action.settings ) ) {
return state;
const merged = { ...state, ...updates };

for ( const clientId in updates ) {
if ( ! updates[ clientId ] ) {
delete merged[ clientId ];
}
}

return {
...state,
[ clientId ]: action.settings,
};
return merged;
}
}
return state;
Expand Down

0 comments on commit 8bd3d46

Please sign in to comment.