From 8b07525c3d5e12b2c26fd3557eebdada9500e32e Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Tue, 18 Jun 2024 04:54:04 +0200 Subject: [PATCH] Performance: run block variation hook only for matches (#62617) Co-authored-by: ellatrix Co-authored-by: aaronrobertshaw --- .../src/hooks/block-style-variation.js | 25 ++++++++++++++++--- packages/block-editor/src/hooks/utils.js | 4 ++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/hooks/block-style-variation.js b/packages/block-editor/src/hooks/block-style-variation.js index ee02b97d216704..964f0d19bb8616 100644 --- a/packages/block-editor/src/hooks/block-style-variation.js +++ b/packages/block-editor/src/hooks/block-style-variation.js @@ -17,6 +17,23 @@ import { useStyleOverride } from './utils'; import { store as blockEditorStore } from '../store'; import { globalStylesDataKey } from '../store/private-keys'; +const VARIATION_PREFIX = 'is-style-'; + +function getVariationMatches( className ) { + if ( ! className ) { + return []; + } + return className.split( /\s+/ ).reduce( ( matches, name ) => { + if ( name.startsWith( VARIATION_PREFIX ) ) { + const match = name.slice( VARIATION_PREFIX.length ); + if ( match !== 'default' ) { + matches.push( match ); + } + } + return matches; + }, [] ); +} + /** * Get the first block style variation that has been registered from the class string. * @@ -28,14 +45,13 @@ import { globalStylesDataKey } from '../store/private-keys'; function getVariationNameFromClass( className, registeredStyles = [] ) { // The global flag affects how capturing groups work in JS. So the regex // below will only return full CSS classes not just the variation name. - const matches = className?.match( /\bis-style-(?!default)(\S+)\b/g ); + const matches = getVariationMatches( className ); if ( ! matches ) { return null; } - for ( const variationClass of matches ) { - const variation = variationClass.substring( 9 ); // Remove 'is-style-' prefix. + for ( const variation of matches ) { if ( registeredStyles.some( ( style ) => style.name === variation ) ) { return variation; } @@ -94,7 +110,7 @@ function useBlockProps( { name, className, clientId } ) { const registeredStyles = getBlockStyles( name ); const variation = getVariationNameFromClass( className, registeredStyles ); - const variationClass = `is-style-${ variation }-${ clientId }`; + const variationClass = `${ VARIATION_PREFIX }${ variation }-${ clientId }`; const { settings, styles } = useBlockSyleVariation( name, @@ -152,5 +168,6 @@ function useBlockProps( { name, className, clientId } ) { export default { hasSupport: () => true, attributeKeys: [ 'className' ], + isMatch: ( { className } ) => getVariationMatches( className ).length > 0, useBlockProps, }; diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 4338262300c618..d4eb7df553d3c0 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -582,6 +582,7 @@ export function createBlockListBlockFilter( features ) { hasSupport, attributeKeys = [], useBlockProps, + isMatch, } = feature; const neededProps = {}; @@ -595,7 +596,8 @@ export function createBlockListBlockFilter( features ) { // Skip rendering if none of the needed attributes are // set. ! Object.keys( neededProps ).length || - ! hasSupport( props.name ) + ! hasSupport( props.name ) || + ( isMatch && ! isMatch( neededProps ) ) ) { return null; }