Skip to content

Enable networking by default #1225

Closed
Closed

Description

@bgrgicak

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.

@adamziel @brandonpayton what do you think?

Activity

  1. adamziel commented on Apr 11, 2024

    @adamziel
    Collaborator

    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.

  2. bgrgicak commented on Apr 11, 2024

    @bgrgicak
    CollaboratorAuthor

    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.

  3. brandonpayton commented on Apr 11, 2024

    @brandonpayton
    Member

    @adamziel @bgrgicak, what does the performance cost of enabling networking come from?

  4. adamziel commented on Apr 11, 2024

    @adamziel
    Collaborator

    @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.

  5. brandonpayton commented on Apr 11, 2024

    @brandonpayton
    Member

    @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?

  6. adamziel commented on Apr 11, 2024

    @adamziel
    Collaborator

    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.

  7. flexseth commented on Apr 25, 2024

    @flexseth
    Collaborator

    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.

    Speculative Loading - could be helpful to offset speed loss
    https://make.wordpress.org/core/2024/04/09/speculative-loading-in-wordpress/

  8. moved this to Project: Up Soon in Playground Boardon Jun 30, 2024
  9. moved this from Project: Triage to Project: Not now in Playground Boardon Jul 1, 2024
  10. adamziel commented on Nov 22, 2024

    @adamziel
    Collaborator

    With networking disabled, the file editor in wp-admin and other features based on the loopback request don't work:

    Image

    I'd love to get networking enabled by default sooner than later.

  11. ajitbohra commented on Nov 22, 2024

    @ajitbohra
    Member

    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.

  12. jeffpaul commented on May 12, 2025

    @jeffpaul
    Member

    @adamziel given other related issues appear to be resolved, what's the blocker in enabling networking by default?

  13. adamziel commented on May 12, 2025

    @adamziel
    Collaborator

    @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.

  14. adamziel commented on Jun 9, 2025

    @adamziel
    Collaborator

    We'd have to find a way of making this function faster:

    public static function check_for_updates() {
        wp_version_check();
        wp_update_plugins();
        wp_update_themes();
    }

    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:

    • 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.

  15. adamziel commented on Jun 9, 2025

    @adamziel
    Collaborator

    wp-admin loads 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:

    <?php
    
    set_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" }}
  16. adamziel commented on Jun 9, 2025

    @adamziel
    Collaborator

    Alternatively, we could:

    • 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.

  17. adamziel commented on Jun 24, 2025

    @adamziel
    Collaborator

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions