From 51fc0862ca804e7681d4b95fd9d5d58ab401ced1 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:28:07 +0100 Subject: [PATCH] Site Editor: speed up load by preloading home and front-page templates (#66579) Co-authored-by: ellatrix Co-authored-by: Mamaduka --- lib/compat/wordpress-6.8/preload.php | 2 + packages/core-data/src/resolvers.js | 71 +++----------- packages/core-data/src/selectors.ts | 32 ------ .../use-init-edited-entity-from-url.js | 97 ++++++------------- 4 files changed, 49 insertions(+), 153 deletions(-) diff --git a/lib/compat/wordpress-6.8/preload.php b/lib/compat/wordpress-6.8/preload.php index 0805ace4233d5..b9e03802a58e9 100644 --- a/lib/compat/wordpress-6.8/preload.php +++ b/lib/compat/wordpress-6.8/preload.php @@ -28,6 +28,8 @@ function gutenberg_block_editor_preload_paths_6_8( $paths, $context ) { 'url', ) ); + $paths[] = '/wp/v2/templates/lookup?slug=front-page'; + $paths[] = '/wp/v2/templates/lookup?slug=home'; } // Preload theme and global styles paths. diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index d3980b89e8fc5..a3bbd37f2d7c2 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -563,58 +563,6 @@ export const getAutosave = await resolveSelect.getAutosaves( postType, postId ); }; -/** - * Retrieve the frontend template used for a given link. - * - * @param {string} link Link. - */ -export const __experimentalGetTemplateForLink = - ( link ) => - async ( { dispatch, resolveSelect } ) => { - let template; - try { - // This is NOT calling a REST endpoint but rather ends up with a response from - // an Ajax function which has a different shape from a WP_REST_Response. - template = await apiFetch( { - url: addQueryArgs( link, { - '_wp-find-template': true, - } ), - } ).then( ( { data } ) => data ); - } catch ( e ) { - // For non-FSE themes, it is possible that this request returns an error. - } - - if ( ! template ) { - return; - } - - const record = await resolveSelect.getEntityRecord( - 'postType', - 'wp_template', - template.id - ); - - if ( record ) { - dispatch.receiveEntityRecords( - 'postType', - 'wp_template', - [ record ], - { - 'find-template': link, - } - ); - } - }; - -__experimentalGetTemplateForLink.shouldInvalidate = ( action ) => { - return ( - ( action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS' ) && - action.invalidateCache && - action.kind === 'postType' && - action.name === 'wp_template' - ); -}; - export const __experimentalGetCurrentGlobalStylesId = () => async ( { dispatch, resolveSelect } ) => { @@ -801,13 +749,26 @@ export const getNavigationFallbackId = export const getDefaultTemplateId = ( query ) => - async ( { dispatch } ) => { - const template = await apiFetch( { + async ( { dispatch, registry } ) => { + const response = await apiFetch( { path: addQueryArgs( '/wp/v2/templates/lookup', query ), + parse: false, } ); + const template = await response.json(); // Endpoint may return an empty object if no template is found. if ( template?.id ) { - dispatch.receiveDefaultTemplateId( query, template.id ); + registry.batch( () => { + dispatch.receiveDefaultTemplateId( query, template.id ); + dispatch.receiveEntityRecords( 'postType', 'wp_template', [ + template, + ] ); + // Avoid further network requests. + dispatch.finishResolution( 'getEntityRecord', [ + 'postType', + 'wp_template', + template.id, + ] ); + } ); } }; diff --git a/packages/core-data/src/selectors.ts b/packages/core-data/src/selectors.ts index 9acadd5c0c0e7..7ea8c2f7f26d5 100644 --- a/packages/core-data/src/selectors.ts +++ b/packages/core-data/src/selectors.ts @@ -1284,38 +1284,6 @@ export function getReferenceByDistinctEdits( state ) { return state.editsReference; } -/** - * Retrieve the frontend template used for a given link. - * - * @param state Editor state. - * @param link Link. - * - * @return The template record. - */ -export function __experimentalGetTemplateForLink( - state: State, - link: string -): Optional< ET.Updatable< ET.WpTemplate > > | null | false { - const records = getEntityRecords< ET.WpTemplate >( - state, - 'postType', - 'wp_template', - { - 'find-template': link, - } - ); - - if ( records?.length ) { - return getEditedEntityRecord< ET.WpTemplate >( - state, - 'postType', - 'wp_template', - records[ 0 ].id - ); - } - return null; -} - /** * Retrieve the current theme's base global styles * diff --git a/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js b/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js index 35eeb5963fb54..3498bed4c99a5 100644 --- a/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js +++ b/packages/edit-site/src/components/sync-state-with-url/use-init-edited-entity-from-url.js @@ -31,47 +31,33 @@ const postTypesWithoutParentTemplate = [ const authorizedPostTypes = [ 'page', 'post' ]; function useResolveEditedEntityAndContext( { postId, postType } ) { - const { - hasLoadedAllDependencies, - homepageId, - postsPageId, - url, - frontPageTemplateId, - } = useSelect( ( select ) => { - const { getEntityRecord, getEntityRecords } = select( coreDataStore ); - const siteData = getEntityRecord( 'root', 'site' ); - const base = getEntityRecord( 'root', '__unstableBase' ); - const templates = getEntityRecords( 'postType', TEMPLATE_POST_TYPE, { - per_page: -1, - } ); - const _homepageId = - siteData?.show_on_front === 'page' && - [ 'number', 'string' ].includes( typeof siteData.page_on_front ) && - !! +siteData.page_on_front // We also need to check if it's not zero(`0`). - ? siteData.page_on_front.toString() - : null; - const _postsPageId = - siteData?.show_on_front === 'page' && - [ 'number', 'string' ].includes( typeof siteData.page_for_posts ) - ? siteData.page_for_posts.toString() - : null; - let _frontPageTemplateId; - if ( templates ) { - const frontPageTemplate = templates.find( - ( t ) => t.slug === 'front-page' - ); - _frontPageTemplateId = frontPageTemplate - ? frontPageTemplate.id - : false; - } - return { - hasLoadedAllDependencies: !! base && !! siteData, - homepageId: _homepageId, - postsPageId: _postsPageId, - url: base?.home, - frontPageTemplateId: _frontPageTemplateId, - }; - }, [] ); + const { hasLoadedAllDependencies, homepageId, postsPageId } = useSelect( + ( select ) => { + const { getEntityRecord } = select( coreDataStore ); + const siteData = getEntityRecord( 'root', 'site' ); + const _homepageId = + siteData?.show_on_front === 'page' && + [ 'number', 'string' ].includes( + typeof siteData.page_on_front + ) && + !! +siteData.page_on_front // We also need to check if it's not zero(`0`). + ? siteData.page_on_front.toString() + : null; + const _postsPageId = + siteData?.show_on_front === 'page' && + [ 'number', 'string' ].includes( + typeof siteData.page_for_posts + ) + ? siteData.page_for_posts.toString() + : null; + return { + hasLoadedAllDependencies: !! siteData, + homepageId: _homepageId, + postsPageId: _postsPageId, + }; + }, + [] + ); /** * This is a hook that recreates the logic to resolve a template for a given WordPress postID postTypeId @@ -99,7 +85,6 @@ function useResolveEditedEntityAndContext( { postId, postType } ) { getEditedEntityRecord, getEntityRecords, getDefaultTemplateId, - __experimentalGetTemplateForLink, } = select( coreDataStore ); function resolveTemplateForPostTypeAndId( @@ -111,15 +96,7 @@ function useResolveEditedEntityAndContext( { postId, postType } ) { postTypeToResolve === 'page' && homepageId === postIdToResolve ) { - // We're still checking whether the front page template exists. - // Don't resolve the template yet. - if ( frontPageTemplateId === undefined ) { - return undefined; - } - - if ( !! frontPageTemplateId ) { - return frontPageTemplateId; - } + return getDefaultTemplateId( { slug: 'front-page' } ); } const editedEntity = getEditedEntityRecord( @@ -135,8 +112,7 @@ function useResolveEditedEntityAndContext( { postId, postType } ) { postTypeToResolve === 'page' && postsPageId === postIdToResolve ) { - return __experimentalGetTemplateForLink( editedEntity.link ) - ?.id; + return getDefaultTemplateId( { slug: 'home' } ); } // First see if the post/page has an assigned template and fetch it. const currentTemplateSlug = editedEntity.template; @@ -194,20 +170,9 @@ function useResolveEditedEntityAndContext( { postId, postType } ) { } // If we're not rendering a specific page, use the front page template. - if ( url ) { - const template = __experimentalGetTemplateForLink( url ); - return template?.id; - } + return getDefaultTemplateId( { slug: 'front-page' } ); }, - [ - homepageId, - postsPageId, - hasLoadedAllDependencies, - url, - postId, - postType, - frontPageTemplateId, - ] + [ homepageId, postsPageId, hasLoadedAllDependencies, postId, postType ] ); const context = useMemo( () => {