Skip to content

Commit

Permalink
Improve the Patterns library rendering performance (#21322)
Browse files Browse the repository at this point in the history
Co-Authored-By: Andrew Duthie <andrew@andrewduthie.com>
  • Loading branch information
youknowriad and aduth authored Apr 3, 2020
1 parent 969bbe9 commit 1589d81
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 21 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/block-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@wordpress/is-shallow-equal": "file:../is-shallow-equal",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/priority-queue": "file:../priority-queue",
"@wordpress/rich-text": "file:../rich-text",
"@wordpress/token-list": "file:../token-list",
"@wordpress/url": "file:../url",
Expand Down
36 changes: 28 additions & 8 deletions packages/block-editor/src/components/block-patterns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { __, sprintf } from '@wordpress/i18n';
* Internal dependencies
*/
import BlockPreview from '../block-preview';
import useAsyncList from './use-async-list';

function BlockPattern( { pattern, onClick } ) {
const { title, content } = pattern;
Expand All @@ -34,14 +35,26 @@ function BlockPattern( { pattern, onClick } ) {
tabIndex={ 0 }
>
<div className="block-editor-patterns__item-preview">
<BlockPreview blocks={ blocks } />
<BlockPreview blocks={ blocks } __experimentalPadding={ 8 } />
</div>
<div className="block-editor-patterns__item-title">{ title }</div>
</div>
);
}

function BlockPatternPlaceholder( { pattern } ) {
const { title } = pattern;

return (
<div className="block-editor-patterns__item is-placeholder">
<div className="block-editor-patterns__item-preview"></div>
<div className="block-editor-patterns__item-title">{ title }</div>
</div>
);
}

function BlockPatterns( { patterns } ) {
const currentShownPatterns = useAsyncList( patterns );
const getBlockInsertionPoint = useSelect( ( select ) => {
return select( 'core/block-editor' ).getBlockInsertionPoint;
} );
Expand Down Expand Up @@ -69,13 +82,20 @@ function BlockPatterns( { patterns } ) {

return (
<div className="block-editor-patterns">
{ patterns.map( ( pattern, index ) => (
<BlockPattern
key={ index }
pattern={ pattern }
onClick={ onClickPattern }
/>
) ) }
{ patterns.map( ( pattern, index ) =>
currentShownPatterns[ index ] === pattern ? (
<BlockPattern
key={ index }
pattern={ pattern }
onClick={ onClickPattern }
/>
) : (
<BlockPatternPlaceholder
key={ index }
pattern={ pattern }
/>
)
) }
</div>
);
}
Expand Down
10 changes: 5 additions & 5 deletions packages/block-editor/src/components/block-patterns/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
.block-editor-patterns__item {
background: $white;
border-radius: $radius-block-ui;
padding: $grid-unit-20;

&.is-placeholder .block-editor-patterns__item-preview {
min-height: 100px;
}
}

.block-editor-patterns__item {
Expand All @@ -30,11 +33,8 @@
}
}

.block-editor-patterns__item-preview {
padding: $grid-unit-20;
}

.block-editor-patterns__item-title {
text-align: center;
padding: 10px 0;
padding: $grid-unit-20;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* WordPress dependencies
*/
import { useEffect, useReducer } from '@wordpress/element';
import { createQueue } from '@wordpress/priority-queue';

function listReducer( state, action ) {
if ( action.type === 'reset' && state.length !== 0 ) {
return [];
}

if ( action.type === 'append' ) {
return [ ...state, action.item ];
}

return state;
}

function useAsyncList( list ) {
const [ current, dispatch ] = useReducer( listReducer, [] );

useEffect( () => {
dispatch( { type: 'reset' } );
const asyncQueue = createQueue();
const append = ( index = 0 ) => () => {
if ( list.length <= index ) {
return;
}
dispatch( { type: 'append', item: list[ index ] } );
asyncQueue.add( {}, append( index + 1 ) );
};
asyncQueue.add( {}, append( 0 ) );

return () => asyncQueue.reset();
}, [ list ] );

return current;
}

export default useAsyncList;
13 changes: 10 additions & 3 deletions packages/block-editor/src/components/block-preview/auto.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useResizeObserver } from '@wordpress/compose';
*/
import BlockList from '../block-list';

function AutoBlockPreview( { viewportWidth } ) {
function AutoBlockPreview( { viewportWidth, __experimentalPadding } ) {
const [
containerResizeListener,
{ width: containerWidth },
Expand All @@ -19,19 +19,26 @@ function AutoBlockPreview( { viewportWidth } ) {
{ height: contentHeight },
] = useResizeObserver();

const scale =
( containerWidth - 2 * __experimentalPadding ) / viewportWidth;

return (
<div
className="block-editor-block-preview__container editor-styles-wrapper"
aria-hidden
style={ {
height: ( contentHeight * containerWidth ) / viewportWidth,
height: contentHeight * scale + 2 * __experimentalPadding,
padding: __experimentalPadding,
} }
>
{ containerResizeListener }
<Disabled
style={ {
transform: `scale(${ containerWidth / viewportWidth })`,
transform: `scale(${ scale })`,
width: viewportWidth,
left: __experimentalPadding,
right: __experimentalPadding,
top: __experimentalPadding,
} }
className="block-editor-block-preview__content"
>
Expand Down
7 changes: 6 additions & 1 deletion packages/block-editor/src/components/block-preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import AutoHeightBlockPreview from './auto';
*
* @return {WPComponent} The component to be rendered.
*/
export function BlockPreview( { blocks, viewportWidth = 700 } ) {
export function BlockPreview( {
blocks,
__experimentalPadding = 0,
viewportWidth = 700,
} ) {
const settings = useSelect( ( select ) =>
select( 'core/block-editor' ).getSettings()
);
Expand All @@ -44,6 +48,7 @@ export function BlockPreview( { blocks, viewportWidth = 700 } ) {
<AutoHeightBlockPreview
key={ recompute }
viewportWidth={ viewportWidth }
__experimentalPadding={ __experimentalPadding }
/>
</BlockEditorProvider>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/priority-queue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ queue.add( ctx2, () => console.log( 'This will be printed second' ) );

_Returns_

- `WPPriorityQueue`: Queue object with `add` and `flush` methods.
- `WPPriorityQueue`: Queue object with `add`, `flush` and `reset` methods.


<!-- END TOKEN(Autogenerated API docs) -->
Expand Down
25 changes: 22 additions & 3 deletions packages/priority-queue/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,20 @@ import requestIdleCallback from './request-idle-callback';
* @typedef {(element:WPPriorityQueueContext)=>boolean} WPPriorityQueueFlush
*/

/**
* Reset the queue.
*
* @typedef {()=>void} WPPriorityQueueReset
*/

/**
* Priority queue instance.
*
* @typedef {Object} WPPriorityQueue
*
* @property {WPPriorityQueueAdd} add Add callback to queue for context.
* @property {WPPriorityQueueFlush} flush Flush queue for context.
* @property {WPPriorityQueueReset} reset Reset queue.
*/

/**
Expand All @@ -56,14 +63,14 @@ import requestIdleCallback from './request-idle-callback';
* queue.add( ctx2, () => console.log( 'This will be printed second' ) );
*```
*
* @return {WPPriorityQueue} Queue object with `add` and `flush` methods.
* @return {WPPriorityQueue} Queue object with `add`, `flush` and `reset` methods.
*/
export const createQueue = () => {
/** @type {WPPriorityQueueContext[]} */
const waitingList = [];
let waitingList = [];

/** @type {WeakMap<WPPriorityQueueContext,WPPriorityQueueCallback>} */
const elementsMap = new WeakMap();
let elementsMap = new WeakMap();

let isRunning = false;

Expand Down Expand Up @@ -143,8 +150,20 @@ export const createQueue = () => {
return true;
};

/**
* Reset the queue without running the pending callbacks.
*
* @type {WPPriorityQueueReset}
*/
const reset = () => {
waitingList = [];
elementsMap = new WeakMap();
isRunning = false;
};

return {
add,
flush,
reset,
};
};

0 comments on commit 1589d81

Please sign in to comment.