resourceloader: Preload base modules request from startup module
authorTimo Tijhof <krinklemail@gmail.com>
Tue, 18 Jul 2017 02:36:25 +0000 (21:36 -0500)
committerKrinkle <krinklemail@gmail.com>
Fri, 1 Sep 2017 03:24:35 +0000 (03:24 +0000)
This allows browsers that support W3C Preload <https://www.w3.org/TR/preload/>,
to start downloading and parsing the second load.php JavaScript request
as soon as the headers of the startup module arrive.

Before:
- HTML request, response start.
|\- Discover <script src async> for startup.js, request, response start.
| \ - Startup response end, JS parsing.
|  |
|__|- HTML parsing and rendering yields for async JS execution.
   \- JavaScript inserts <script>, Base-modules request starts. <<<

After:
- HTML request, response start.
|\- Discover <script src async> for startup.js, request, response start
  \ - Base-modules request starts. <<<
|  |- Startup response end, JS parsing.
|  |
|__|- HTML parsing and rendering yields for async JS execution.
   \- JavaScript inserts <script>. (Base-modules req on-going, or done)

On local testing with "Slow 3G" network throttling in Chrome,
this reduced page load time (window.onload, time to interaction for JS)
by about 1 second (from 14s to 13s).
See also https://phabricator.wikimedia.org/T164299#3572231

Bug: T164299
Change-Id: I7047f4ab881947cf3392256087cc5a0cb177dd3a

includes/resourceloader/ResourceLoaderStartUpModule.php

index 8973fe3..d535ffc 100644 (file)
@@ -296,6 +296,16 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                return true;
        }
 
+       /**
+        * @return array
+        */
+       public function getPreloadLinks( ResourceLoaderContext $context ) {
+               $url = self::getStartupModulesUrl( $context );
+               return [
+                       $url => [ 'as' => 'script' ]
+               ];
+       }
+
        /**
         * Base modules required for the base environment of ResourceLoader
         *
@@ -359,6 +369,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                }, [
                        '$VARS.wgLegacyJavaScriptGlobals' => $this->getConfig()->get( 'LegacyJavaScriptGlobals' ),
                        '$VARS.configuration' => $this->getConfigSettings( $context ),
+                       // This url may be preloaded. See getPreloadLinks().
                        '$VARS.baseModulesUri' => self::getStartupModulesUrl( $context ),
                ] );
                $pairs['$CODE.registrations()'] = str_replace(