Skip to content

Commit

Permalink
Perf: batch block list settings in single action (#61329)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
  • 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

1 comment on commit 8bd3d46

@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 8bd3d46.
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/9175001408
📝 Reported issues:

Please sign in to comment.