You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Having networking disabled by default is a performance improvement, but working networking is something most of us expect out of the box. I suggest that we enable networking by default and allow disabling it to improve user experience.
I'd be more than happy to do that if it didn't add 5-10 seconds to loading /wp-admin and random screens. It makes the difference between "oh it's so fast" and "oh it's so slow" at the expense of an occasional "oh something isn't loading". Perhaps we could tactically block or pre-fetch specific api.wp.org requests though to make it faster.
Perhaps we could tactically block or pre-fetch specific api.wp.org requests though to make it faster.
We will eventually need to preload "everything" if we want offline support (#1086). When we have that, it might be a good time to reconsider enabling networking by default.
@brandonpayton/wp-admin won't render until all the network calls are finished, and requesting api.wp.org using fetch() is not as fast as native network implementation running on a server with a fast network connection.
I think we could pre-fetch or stub most of them! I'd only run "synchronously" the ones where it actually fetches a filtered list of patterns, plugins, themes.
I think we could pre-fetch or stub most of them! I'd only run "synchronously" the ones where it actually fetches a filtered list of patterns, plugins, themes.
New people using Playground get the impression that it's a tool with limitations and meant to be used in a limited capacity. I have seen people struggle at meetups or when testing out for quick demos, and the plugin or theme install screen does not work as expected.
@jeffpaul caching the initial API requests sent by WordPress/wp-admin. A fresh WordPress install issues I think 3 requests and it makes a big difference for the initial rendering time.
In a perfect world, a fresh Playground install would ship three cached responses and render wp-admin very fast. I'm not sure how cache-able these responses are, though. For example, if a Blueprint installs a plugin, we may need to re-request the versions updates endpoint. Still, not having to do that for the default Playground setup would be lovely.
Shipping cached responses with the build would only work for the default Playground site as the requests are parametrized with the current WordPress installation's plugins and themes.
Here's a two ideas:
Set update_plugins, update_theme, and update_core transients to tell WordPress we've just checked for updates. On the up side, it would prevent the initial burst of requests. On the down side, it could confuse developers as in "why is it not checking for updates?" Maybe that's acceptable with the right documentation.
Pre-fetch the responses immediately after the Blueprint is executed. Three parallel upfront requests would be faster than three sequential just-in-time requests. By the time WordPress requests the first update-related API endpoint we should have the responses ready and could just provide them without actually sending a request. The downside is the added complexity and maintenance burden – we'd need to keep the TypeScript fetch() implementation in sync with the WordPress core implementation. This could mean maintaining multiple implementations of optimistic caching – one per WordPress version.
Don't do anything and just have a slower initial wp-admin load. I don't like that because these fetches can sometimes take up to 5 or even 10 more seconds.
I don't have a fourth idea. The transients don't sound too bad, though. Also, we could actually pre-fetch the API response for WordPress core versions as that doesn't depend on the exact plugins and themes installed and I also don't expect that logic to change that much in WordPress.
The PHP code pre-sets all the update-related transients to an initial value. This way WordPress skips the request on the initial wp-admin page load. Here's a formatted version of that code:
<?phpset_site_transient(
'php_check_' . md5( PHP_VERSION ),
// Hardcoded values the demo. We could use an empty array or prepare a set of pre-cached// responses for every supported PHP version:
[
'recommended_version' => '7.4',
'minimum_version' => '7.2.24',
'is_supported' => true,
'is_secure' => true,
'is_acceptable' => true,
]
);
set_site_transient( 'update_core', (object) [
'updates' => [],
'last_checked' => time(),
'version_checked' => wp_get_wp_version(),
] );
set_site_transient( 'update_themes', (object) [
'updates' => [],
'last_checked' => time(),
'version_checked' => wp_get_wp_version(),
] );
set_site_transient( 'update_plugins', (object) [
'updates' => [],
'last_checked' => time(),
'version_checked' => wp_get_wp_version(),
] );
There's one more update-related request wp-admin sends – to https://api.wordpress.org/core/browse-happy/1.1/. It checks the compatibility of the current browser based on the user agent string. We could also initialize that transient in Playground:
<?php// Note: $_SERVER['HTTP_USER_AGENT'] is not available in Blueprint-trigerred runPHP step right now.// We could either make it available there, or provide that information from TypeScript via an ENV variable.set_site_transient( 'browser_' . md5( $_SERVER['HTTP_USER_AGENT'] ), (object) [
'name' => 'Chrome',
'version' => '137.0.0.0',
'platform' => 'Macintosh',
'update_url' => 'https://www.google.com/chrome',
'img_src' => 'http://s.w.org/images/browsers/chrome.png?1',
'img_src_ssl' => 'https://s.w.org/images/browsers/chrome.png?1',
'current_version' => '18',
'upgrade' => false,
'insecure' => false,
'mobile' => false,
] );
Open questions:
What would make good initial values? Should we pre-populate any data, e.g. PHP compat and latest WordPress versions?
What would be a good expiry for each of those transient? 10 minutes? Their only purpose is to speed up the initial load, I think it's okay to actually run these requests after a while.
Should Blueprints offer a way of not initializing those transients? e.g. {"features": { "networking": "enable-without-transients" }}
Run wp_check_php_version(); wp_version_check(); wp_update_plugins(); wp_update_themes(); immediately after the Blueprint has finished running.
Intercept every request, store the Request object, respond with a fake 500 or so response.
Start fetch()-ing the intercepted Requests in parallel
Redirect the user to /wp-admin/
When a familiar request is spotted, await its promise and provide the response from the fetch() we started earlier
This would provide WordPress with fresh API responses on the first wp-admin load without:
Re-implementing and maintain the update fetching logic
Using fake and potentially stale response data
Complicate the build process
Introducing a third "networking" state (enabled, disabled, enabled-without-transients)
Complexity-wise, we'd need a single, additional php.run() call, a temporary request handler, and a way to reuse cached responses on the first wp-admin load. It seems fine. I think I like this solution the most.
I've just merged #2296 and enabled networking by default on https://playground.wordpress.net/ 🎉 I'm going to close this issue. If anything breaks, please report the problems as usual.
Activity
adamziel commentedon Apr 11, 2024
I'd be more than happy to do that if it didn't add 5-10 seconds to loading
/wp-adminand random screens. It makes the difference between "oh it's so fast" and "oh it's so slow" at the expense of an occasional "oh something isn't loading". Perhaps we could tactically block or pre-fetch specificapi.wp.orgrequests though to make it faster.bgrgicak commentedon Apr 11, 2024
We will eventually need to preload "everything" if we want offline support (#1086). When we have that, it might be a good time to reconsider enabling
networkingby default.brandonpayton commentedon Apr 11, 2024
@adamziel @bgrgicak, what does the performance cost of enabling networking come from?
adamziel commentedon Apr 11, 2024
@brandonpayton
/wp-adminwon't render until all the network calls are finished, and requestingapi.wp.orgusingfetch()is not as fast as native network implementation running on a server with a fast network connection.brandonpayton commentedon Apr 11, 2024
@adamziel thanks, that helps! As a random thought, are there any api.wp.org requests that we could reasonably intercept and provide stub data for?
adamziel commentedon Apr 11, 2024
I think we could pre-fetch or stub most of them! I'd only run "synchronously" the ones where it actually fetches a filtered list of patterns, plugins, themes.
flexseth commentedon Apr 25, 2024
Speculative Loading - could be helpful to offset speed loss
https://make.wordpress.org/core/2024/04/09/speculative-loading-in-wordpress/
adamziel commentedon Nov 22, 2024
With networking disabled, the file editor in wp-admin and other features based on the loopback request don't work:
I'd love to get networking enabled by default sooner than later.
ajitbohra commentedon Nov 22, 2024
New people using Playground get the impression that it's a tool with limitations and meant to be used in a limited capacity. I have seen people struggle at meetups or when testing out for quick demos, and the plugin or theme install screen does not work as expected.
jeffpaul commentedon May 12, 2025
@adamziel given other related issues appear to be resolved, what's the blocker in enabling networking by default?
adamziel commentedon May 12, 2025
@jeffpaul caching the initial API requests sent by WordPress/wp-admin. A fresh WordPress install issues I think 3 requests and it makes a big difference for the initial rendering time.
In a perfect world, a fresh Playground install would ship three cached responses and render wp-admin very fast. I'm not sure how cache-able these responses are, though. For example, if a Blueprint installs a plugin, we may need to re-request the versions updates endpoint. Still, not having to do that for the default Playground setup would be lovely.
adamziel commentedon Jun 9, 2025
We'd have to find a way of making this function faster:
It runs a few sequential requests to:
Shipping cached responses with the build would only work for the default Playground site as the requests are parametrized with the current WordPress installation's plugins and themes.
Here's a two ideas:
update_plugins,update_theme, andupdate_coretransients to tell WordPress we've just checked for updates. On the up side, it would prevent the initial burst of requests. On the down side, it could confuse developers as in "why is it not checking for updates?" Maybe that's acceptable with the right documentation.I don't have a fourth idea. The transients don't sound too bad, though. Also, we could actually pre-fetch the API response for WordPress core versions as that doesn't depend on the exact plugins and themes installed and I also don't expect that logic to change that much in WordPress.
adamziel commentedon Jun 9, 2025
wp-adminloads really fast with this Blueprint:{ "login": true, "features": { "networking": true }, "landingPage": "/wp-admin/", "steps": [ { "step": "runPHP", "code": "<?php require '/wordpress/wp-load.php'; set_site_transient( 'php_check_' . md5( PHP_VERSION ), ['recommended_version'=> '7.4','minimum_version' => '7.2.24','is_supported' => true,'is_secure' => true,'is_acceptable' => true], WEEK_IN_SECONDS ); set_site_transient( 'update_core', (object)['updates' => [], 'last_checked' => time(), 'version_checked' => wp_get_wp_version()] ); set_site_transient( 'update_themes', (object)['updates' => [], 'last_checked' => time(), 'version_checked' => wp_get_wp_version()] ); set_site_transient( 'update_plugins', (object)['updates' => [], 'last_checked' => time(), 'version_checked' => wp_get_wp_version()] );" } ] }The PHP code pre-sets all the update-related transients to an initial value. This way WordPress skips the request on the initial wp-admin page load. Here's a formatted version of that code:
There's one more update-related request
wp-adminsends – tohttps://api.wordpress.org/core/browse-happy/1.1/. It checks the compatibility of the current browser based on the user agent string. We could also initialize that transient in Playground:Open questions:
{"features": { "networking": "enable-without-transients" }}adamziel commentedon Jun 9, 2025
Alternatively, we could:
wp_check_php_version(); wp_version_check(); wp_update_plugins(); wp_update_themes();immediately after the Blueprint has finished running.Requestobject, respond with a fake 500 or so response.fetch()-ing the intercepted Requests in parallel/wp-admin/fetch()we started earlierThis would provide WordPress with fresh API responses on the first wp-admin load without:
"networking"state (enabled, disabled, enabled-without-transients)Complexity-wise, we'd need a single, additional
php.run()call, a temporary request handler, and a way to reuse cached responses on the first wp-admin load. It seems fine. I think I like this solution the most.[Web] Enable networking by default in Playground web (#2296)
adamziel commentedon Jun 24, 2025
I've just merged #2296 and enabled networking by default on https://playground.wordpress.net/ 🎉 I'm going to close this issue. If anything breaks, please report the problems as usual.