Skip to content

Commit

Permalink
Block preview: build in async rendering (#60425)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: oandregal <[email protected]>
  • Loading branch information
4 people authored Apr 4, 2024
1 parent 0e025fd commit b59d363
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 36 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

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

4 changes: 0 additions & 4 deletions packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,6 @@ Whether the data is loading. `false` by default.

Array of layouts supported. By default, all are: `table`, `grid`, `list`.

### `deferredRendering`: `boolean`

Whether the items should be rendered asynchronously. Useful when there's a field that takes a lot of time (e.g.: previews). `false` by default.

### `onSelectionChange`: `function`

Callback that signals the user selected one of more items, and takes them as parameter. So far, only the `list` view implements it.
Expand Down
2 changes: 0 additions & 2 deletions packages/dataviews/src/dataviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export default function DataViews( {
paginationInfo,
supportedLayouts,
onSelectionChange = defaultOnSelectionChange,
deferredRendering = false,
} ) {
const [ selection, setSelection ] = useState( [] );
const [ openedFilter, setOpenedFilter ] = useState( null );
Expand Down Expand Up @@ -136,7 +135,6 @@ export default function DataViews( {
isLoading={ isLoading }
onSelectionChange={ onSetSelection }
selection={ selection }
deferredRendering={ deferredRendering }
setOpenedFilter={ setOpenedFilter }
/>
<Pagination
Expand Down
8 changes: 2 additions & 6 deletions packages/dataviews/src/view-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
FlexItem,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useAsyncList } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -151,7 +150,6 @@ export default function ViewGrid( {
actions,
isLoading,
getItemId,
deferredRendering,
selection,
onSelectionChange,
} ) {
Expand All @@ -168,9 +166,7 @@ export default function ViewGrid( {
field.id
)
);
const shownData = useAsyncList( data, { step: 3 } );
const usedData = deferredRendering ? shownData : data;
const hasData = !! usedData?.length;
const hasData = !! data?.length;
return (
<>
{ hasData && (
Expand All @@ -181,7 +177,7 @@ export default function ViewGrid( {
className="dataviews-view-grid"
aria-busy={ isLoading }
>
{ usedData.map( ( item ) => {
{ data.map( ( item ) => {
return (
<GridItem
key={ getItemId( item ) }
Expand Down
11 changes: 4 additions & 7 deletions packages/dataviews/src/view-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import classNames from 'classnames';
/**
* WordPress dependencies
*/
import { useAsyncList, useInstanceId } from '@wordpress/compose';
import { useInstanceId } from '@wordpress/compose';
import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
Expand Down Expand Up @@ -128,13 +128,10 @@ export default function ViewList( {
getItemId,
onSelectionChange,
selection,
deferredRendering,
id: preferredId,
} ) {
const baseId = useInstanceId( ViewList, 'view-list', preferredId );
const shownData = useAsyncList( data, { step: 3 } );
const usedData = deferredRendering ? shownData : data;
const selectedItem = usedData?.findLast( ( item ) =>
const selectedItem = data?.findLast( ( item ) =>
selection.includes( item.id )
);

Expand Down Expand Up @@ -166,7 +163,7 @@ export default function ViewList( {
defaultActiveId: getItemDomId( selectedItem ),
} );

const hasData = usedData?.length;
const hasData = data?.length;
if ( ! hasData ) {
return (
<div
Expand All @@ -190,7 +187,7 @@ export default function ViewList( {
role="grid"
store={ store }
>
{ usedData.map( ( item ) => {
{ data.map( ( item ) => {
const id = getItemDomId( item );
return (
<ListItem
Expand Down
8 changes: 2 additions & 6 deletions packages/dataviews/src/view-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useAsyncList } from '@wordpress/compose';
import { unseen, funnel } from '@wordpress/icons';
import {
Button,
Expand Down Expand Up @@ -369,7 +368,6 @@ function ViewTable( {
data,
getItemId,
isLoading = false,
deferredRendering,
selection,
onSelectionChange,
setOpenedFilter,
Expand All @@ -386,7 +384,6 @@ function ViewTable( {
}
} );

const asyncData = useAsyncList( data );
const tableNoticeId = useId();

if ( nextHeaderMenuToFocus ) {
Expand All @@ -409,8 +406,7 @@ function ViewTable( {
! view.hiddenFields.includes( field.id ) &&
! [ view.layout.mediaField ].includes( field.id )
);
const usedData = deferredRendering ? asyncData : data;
const hasData = !! usedData?.length;
const hasData = !! data?.length;
const sortValues = { asc: 'ascending', desc: 'descending' };

const primaryField = fields.find(
Expand Down Expand Up @@ -502,7 +498,7 @@ function ViewTable( {
</thead>
<tbody>
{ hasData &&
usedData.map( ( item, index ) => (
data.map( ( item, index ) => (
<TableRow
key={ getItemId( item ) }
item={ item }
Expand Down
1 change: 1 addition & 0 deletions packages/edit-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@wordpress/plugins": "file:../plugins",
"@wordpress/preferences": "file:../preferences",
"@wordpress/primitives": "file:../primitives",
"@wordpress/priority-queue": "file:../priority-queue",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/reusable-blocks": "file:../reusable-blocks",
"@wordpress/router": "file:../router",
Expand Down
43 changes: 43 additions & 0 deletions packages/edit-site/src/components/async/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* WordPress dependencies
*/
import { useEffect, useState, flushSync } from '@wordpress/element';
import { createQueue } from '@wordpress/priority-queue';

const blockPreviewQueue = createQueue();

/**
* Renders a component at the next idle time.
* @param {*} props
*/
export function Async( { children, placeholder } ) {
const [ shouldRender, setShouldRender ] = useState( false );

// In the future, we could try to use startTransition here, but currently
// react will batch all transitions, which means all previews will be
// rendered at the same time.
// https://react.dev/reference/react/startTransition#caveats
// > If there are multiple ongoing Transitions, React currently batches them
// > together. This is a limitation that will likely be removed in a future
// > release.

useEffect( () => {
const context = {};
blockPreviewQueue.add( context, () => {
// Synchronously run all renders so it consumes timeRemaining.
// See https://github.com/WordPress/gutenberg/pull/48238
flushSync( () => {
setShouldRender( true );
} );
} );
return () => {
blockPreviewQueue.cancel( context );
};
}, [] );

if ( ! shouldRender ) {
return placeholder;
}

return children;
}
12 changes: 7 additions & 5 deletions packages/edit-site/src/components/page-patterns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { usePrevious } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { Async } from '../async';
import Page from '../page';
import {
LAYOUT_GRID,
Expand Down Expand Up @@ -177,10 +178,12 @@ function Preview( { item, categoryId, viewType } ) {
{ isEmpty && isTemplatePart && __( 'Empty template part' ) }
{ isEmpty && ! isTemplatePart && __( 'Empty pattern' ) }
{ ! isEmpty && (
<BlockPreview
blocks={ item.blocks }
viewportWidth={ item.viewportWidth }
/>
<Async>
<BlockPreview
blocks={ item.blocks }
viewportWidth={ item.viewportWidth }
/>
</Async>
) }
</PreviewWrapper>
</div>
Expand Down Expand Up @@ -404,7 +407,6 @@ export default function DataviewsPatterns() {
isLoading={ isResolving }
view={ view }
onChangeView={ onChangeView }
deferredRendering
supportedLayouts={ [ LAYOUT_GRID, LAYOUT_TABLE ] }
/>
</Page>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { privateApis as editorPrivateApis } from '@wordpress/editor';
/**
* Internal dependencies
*/
import { Async } from '../async';
import Page from '../page';
import { default as Link, useLink } from '../routes/link';
import AddNewTemplate from '../add-new-template';
Expand Down Expand Up @@ -173,7 +174,9 @@ function Preview( { item, viewType } ) {
style={ { backgroundColor } }
>
{ viewType === LAYOUT_LIST && ! isEmpty && (
<BlockPreview blocks={ blocks } />
<Async>
<BlockPreview blocks={ blocks } />
</Async>
) }
{ viewType !== LAYOUT_LIST && (
<button
Expand All @@ -186,7 +189,11 @@ function Preview( { item, viewType } ) {
( item.type === TEMPLATE_POST_TYPE
? __( 'Empty template' )
: __( 'Empty template part' ) ) }
{ ! isEmpty && <BlockPreview blocks={ blocks } /> }
{ ! isEmpty && (
<Async>
<BlockPreview blocks={ blocks } />
</Async>
) }
</button>
) }
</div>
Expand Down Expand Up @@ -419,10 +426,6 @@ export default function PageTemplatesTemplateParts( { postType } ) {
view={ view }
onChangeView={ onChangeView }
onSelectionChange={ onSelectionChange }
deferredRendering={
view.type === LAYOUT_GRID ||
! view.hiddenFields?.includes( 'preview' )
}
/>
</Page>
);
Expand Down

0 comments on commit b59d363

Please sign in to comment.