Make WordPress Core

Opened 5 weeks ago

Last modified 4 weeks ago

#65206 assigned enhancement

Site Editor: preload initial canvas REST data

Reported by: extrachill's profile extrachill Owned by: extrachill's profile extrachill
Milestone: 7.1 Priority: normal
Severity: normal Version:
Component: Editor Keywords: has-patch
Focuses: performance Cc:

Description

This ticket tracks the WordPress Core sync/backport for a Gutenberg Site Editor preload change.

The Gutenberg issue/PR are already filed here:

This Core ticket is needed for the corresponding wordpress-develop PR that syncs the PHP preload change into src/wp-admin/site-editor.php.

The Site Editor currently misses several REST API preload paths used during the initial editor canvas load, causing avoidable follow-up REST requests for individual template part records, Query Loop post collections, and public taxonomies.

Observed late REST routes included:

  • /wp/v2/template-parts/<template-part-id>?context=edit
  • /wp/v2/posts?context=edit&offset=0&order=desc&orderby=date&per_page=10&ignore_sticky=false
  • /wp/v2/posts?context=edit&offset=0&order=desc&orderby=date&per_page=3&ignore_sticky=false
  • /wp/v2/taxonomies?context=view

Validation against a Site Editor load benchmark showed the candidate reducing measured load time from 1235ms to 914ms (-321ms / -26.0%) and eliminating the observed late REST resources (5 -> 0).

Change History (16)

This ticket was mentioned in PR #11766 on WordPress/wordpress-develop by @extrachill.


5 weeks ago
#1

## Summary

  • Preloads additional REST responses used during the Site Editor's initial canvas load.
  • Covers individual template part records, Query Loop post collection requests, and public taxonomies.
  • Syncs the related Gutenberg preload change from WordPress/gutenberg#78075.

## Trac ticket
https://core.trac.wordpress.org/ticket/65206

## Gutenberg PR
https://github.com/WordPress/gutenberg/pull/78075

## Testing

  • php -l src/wp-admin/site-editor.php
  • git diff --check
  • Validated via a Site Editor load benchmark on the Gutenberg-side change: 1235ms baseline to 914ms candidate (-321ms / -26.0%), with late measured REST resources reduced from 5 to 0.

## AI assistance

  • AI assistance: Yes
  • Tool(s): OpenCode (GPT-5.5)
  • Used for: Drafting and validating the preload patch plus PR description; Chris reviewed the backport workflow and filed the Trac ticket.

@westonruter commented on PR #11766:


5 weeks ago
#3

I can see that this is successfully eliminating 4 client-side REST API requests:

Before | After

--

https://github.com/user-attachments/assets/f1de5225-418f-4ff1-9e69-e102b9f2c223 | https://github.com/user-attachments/assets/7543d2c3-cce3-46d9-b35b-167a9be63a8c

Is there an opportunity to preload more?

#4 @westonruter
5 weeks ago

  • Milestone changed from Awaiting Review to Future Release
  • Owner set to extrachill
  • Status changed from new to assigned

@extrachill commented on PR #11766:


5 weeks ago
#5

I think there is a strong chance the answer is yes. I will run some more tests and see what I can do. Appreciate your feedback.

@extrachill commented on PR #11766:


5 weeks ago
#6

Thanks for asking whether there was room to preload more. I did a focused sweep of the remaining visible REST requests using the Homeboy Site Editor benchmark rig and REST waterfall diff tooling.

What changed in the latest push:

  • Added GET /wp/v2/types/post?context=edit when the resolved initial template contains a Query Loop.
  • Added the edit-context page tree request: GET /wp/v2/pages?context=edit&per_page=100&_fields=id,link,menu_order,parent,title,type&orderby=menu_order&order=asc.

Evidence from the default TT5 Site Editor scenario:

  • Original baseline: 34 REST requests, 19 unique, 5 measured canvas-phase REST resources, ready around 1209ms.
  • Existing route/template-aware candidate: about 22-23 REST requests, 13 unique, 0 measured canvas-phase REST resources, ready around 925ms.
  • Updated candidate with the two added routes: 20 REST requests, 12 unique, 0 measured canvas-phase REST resources, ready around 894ms over a 3-iteration run.

I also tested additional visible REST routes individually. I did not add them because they either did not satisfy the client preload cache key in this scenario or made the critical path worse:

  • GET /wp-block-editor/v1/navigation-fallback?_embed=true removed its target request, but reintroduced measured resources and slowed readiness.
  • GET /wp/v2/users/me?context=edit, GET /wp/v2/pages?context=view..., GET /wp/v2/menus?..., and GET /wp/v2/wp_pattern_category?... did not remove their target requests when preloaded in this scenario.

Tooling used:

Validation run locally:

  • php -l src/wp-admin/site-editor.php
  • ./vendor/bin/phpcs -s --standard=phpcs.xml.dist src/wp-admin/site-editor.php
  • ./vendor/bin/phpcs -s --standard=phpcompat.xml.dist src/wp-admin/site-editor.php
  • homeboy lint --path /Users/chubes/Developer/wordpress-develop@fix-site-editor-preload-canvas-data --extension nodejs
  • homeboy test ... got through build and QUnit (456 tests, 0 failures), then stopped at local PHPUnit setup because wp-tests-config.php is not configured.

One caveat: this specific two-route follow-up was validated against the default TT5 Site Editor scenario. I previously attempted the additional static/front-page scenario runs, but those were blocked locally by Studio WP-CLI setup timeouts, so I do not want to overclaim full scenario-matrix coverage for these two extra routes.

@westonruter commented on PR #11766:


5 weeks ago
#7

Opening the Home template in the Site Editor is now down to 15 client-side fetches instead of 20:

Before | After

--

https://github.com/user-attachments/assets/f94a7d82-8bbf-41f0-b3d3-d575e3d1d066 | https://github.com/user-attachments/assets/7b482f9d-e22a-4d31-8c12-1023b917780f

@extrachill commented on PR #11766:


5 weeks ago
#8

LFG! 🚀

@westonruter commented on PR #11766:


5 weeks ago
#9

Out of curiosity, I tired preloading _all_ REST API requests for my homepage template in the Site Editor:

$preload_paths[] = '/wp/v2/templates/twentytwentyfive//home?context=edit';
$preload_paths[] = '/wp/v2/wp_pattern_category?context=view&per_page=100&_fields=id%2Cname%2Cdescription%2Cslug';
$preload_paths[] = '/wp/v2/block-patterns/patterns';
$preload_paths[] = '/wp/v2/taxonomies?context=edit&per_page=100';
$preload_paths[] = '/wp/v2/menus?context=view&per_page=100';
$preload_paths[] = '/wp/v2/pages?context=view&parent=0&order=asc&orderby=id&per_page=100';
$preload_paths[] = '/wp/v2/navigation/274?context=edit';
$preload_paths[] = '/wp/v2/pages/82?context=edit';
$preload_paths[] = '/wp/v2/pages/84?context=edit';
$preload_paths[] = '/wp/v2/pages/2?context=edit';
$preload_paths[] = array( '/wp/v2/settings', 'OPTIONS' );
$preload_paths[] = array( '/wp/v2/templates/twentytwentyfive//home', 'OPTIONS' );
$preload_paths[] = array( '/wp/v2/templates', 'OPTIONS' );
$preload_paths[] = array( '/wp/v2/navigation', 'OPTIONS' );
$preload_paths[] = array( '/wp/v2/navigation/274', 'OPTIONS' );

I couldn't get these to get preloaded:

https://github.com/user-attachments/assets/959d5dd0-31a2-416d-bfdb-738ddbafc87f

@extrachill commented on PR #11766:


5 weeks ago
#10

Was there a measurable impact on speed? The test runs I did found that some of the requests actually slowed down the overall load time when preloaded. There's a chance the harness was flawed in some way.

Do you think the 5 requests that you couldn't get preloaded might point to something deeper worth investigating?

This benchmark tooling is so fun to use, I'm happy to keep poking at things to see how fast we can make it without regressions.

@westonruter commented on PR #11766:


5 weeks ago
#11

Well, I couldn't get all of them to be preloaded so I didn't go that far to measure. I was going to try measuring after all of the requests were preloaded. But if requests aren't in the critical rendering path, then indeed it doesn't make sense to preload since then it just slows down the page from being served.

@extrachill commented on PR #11766:


5 weeks ago
#12

Follow-up from the remaining visible REST rows in DevTools: I traced the preloading middleware keys and caller stacks in Gutenberg, and the duplicate OPTIONS rows are separate client-side follow-ups rather than missing server preload declarations in this backport.

Tracked Gutenberg issues:

One diagnostics detail worth preserving: DevTools shows the post-middleware URL with _locale=user, while createPreloadingMiddleware() checks the pre-locale key first. For example, /wp/v2/taxonomies?context=view is the correct preload declaration even when the visible network row is /wp/v2/taxonomies?_locale=user&context=view.

That means this PR/backport should stay focused on predictable server-side Site Editor preload declarations. The remaining duplicate OPTIONS behavior belongs in the linked core-data issues rather than broadening this patch just to chase a zero-request waterfall.

#14 @audrasjb
4 weeks ago

Removing trunk version as this is not going to be shipped with WP 7.0 but in the next releases.

#15 @desrosj
4 weeks ago

  • Version trunk deleted

Since this is an enhancement, there's no first version of WordPress this can be reproduced in. Removing trunk version.

#16 @westonruter
4 weeks ago

  • Milestone changed from Future Release to 7.1
Note: See TracTickets for help on using tickets.