Skip to content
Open
Prev Previous commit
Next Next commit
Simplify fill filtering
  • Loading branch information
jeryj committed Sep 5, 2025
commit e28f37bcb9cfaf2c59a3ca78ab7e3b7c8e1350d7

This file was deleted.

16 changes: 13 additions & 3 deletions packages/block-editor/src/components/block-controls/fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
* Internal dependencies
*/
import useBlockControlsFill from './hook';
import { ContentOnlyFilter } from './content-only-filter';
import { useBlockEditingMode } from '../block-editing-mode';

export default function BlockControlsFill( {
group = 'default',
Expand All @@ -22,14 +22,24 @@ export default function BlockControlsFill( {
group,
__experimentalShareWithChildBlocks
);
const blockEditingMode = useBlockEditingMode();

if ( ! Fill ) {
return null;
}

// Filter children in content-only mode
let filteredChildren = children;
if ( blockEditingMode === 'contentOnly' && Array.isArray( children ) ) {
filteredChildren = children.filter( ( child ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This filter will always create a new Array. For perf reasons I wonder if there's a way to avoid that 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

We can certainly look to memoize.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had the AI write a performance test case to compare:

Memoized - 5 items: 0.188ms average (1000 iterations)
Non-memoized - 5 items: 0.132ms average (1000 iterations)
Difference: 0.055ms (41.7%)

This is significant! The memoized version is actually 41.7% slower than the non-memoized version for small arrays (5 items).

Copy link
Member

Choose a reason for hiding this comment

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

Instead of the Array.isArray check it's better to use React.Children.toArray, which is a targeted helper that converts children to a valid array.

I wouldn't worry about copying children at all. Every React render creates a tremendous amount of arrays and objects and then dumps them after the render is finished.

Also, the fill is typically used as:

<BlockControlsFill>
  <SomeItem />
  <SomeOther Item />
</BlockControlsFill>

Where the children is a new array on every render. It's quite rare that children would stay constant between renders.

return child?.props?.category === 'content';
} );
}

const innerMarkup = (
<>
{ group === 'default' && <ToolbarGroup controls={ controls } /> }
{ children }
{ filteredChildren }
</>
);

Expand All @@ -44,7 +54,7 @@ export default function BlockControlsFill( {
( inner, [ Provider, props ] ) => (
<Provider { ...props }>{ inner }</Provider>
),
<ContentOnlyFilter>{ innerMarkup }</ContentOnlyFilter>
innerMarkup
);
} }
</Fill>
Expand Down