Krinkle has uploaded a new change for review. https://gerrit.wikimedia.org/r/282505
Change subject: [WIP] resourceloader: Avoid request overhead for legacy modules ...................................................................... [WIP] resourceloader: Avoid request overhead for legacy modules Follows-up 0ac4f998. After d790562, legacy modules (added to the top queue) were no longer consistently loaded before the bottom queue due to the top queue being async. The implied dependency was made explicit by 0ac4f998 by awaiting all modules that aren't themselves a legacy module (or a dependency thereof) on the readiness of the legacy modules. This had a negative side-effect of causing an extra HTTP request because we wrongly assumed that the execute() function would not be called before a module from the top queue request finished loading. Thus we wrongly assumed that this waiting would only re-arrange execution (since the legacy modules were already requested in the top queue, it was intended to just ride along the request for that). Instead, what really happened is that the embedded mw.loader.implement() call for user options and tokens naturally triggers the execute() call before the top queue is processed. It thus forces the loader to, at that point, start a request just for the legacy modules (not knowing there is about to be a request for them already as part of the top queue). This could be fixed by moving the top queue to be before the embedded modules and enforcing the embed in a different way. It could also be fixed by debouncing module load calls so they naturally end up as a single request. However for now I'm addressing this by adding legacy modules to the list of modules in the initial load request from the startup module. This naturally makes them available before all others without much overhead. Change-Id: I54f087655e1cde1b8ff1ca5fe56e82f7f7d80965 --- M includes/resourceloader/ResourceLoaderStartUpModule.php M includes/skins/Skin.php M resources/src/mediawiki/mediawiki.js 3 files changed, 23 insertions(+), 36 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/05/282505/1 diff --git a/includes/resourceloader/ResourceLoaderStartUpModule.php b/includes/resourceloader/ResourceLoaderStartUpModule.php index 34866f3..a2cf193 100644 --- a/includes/resourceloader/ResourceLoaderStartUpModule.php +++ b/includes/resourceloader/ResourceLoaderStartUpModule.php @@ -109,7 +109,6 @@ 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass( Title::legalChars() ), 'wgResourceLoaderStorageVersion' => $conf->get( 'ResourceLoaderStorageVersion' ), 'wgResourceLoaderStorageEnabled' => $conf->get( 'ResourceLoaderStorageEnabled' ), - 'wgResourceLoaderLegacyModules' => self::getLegacyModules(), 'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ), 'wgEnableUploads' => $conf->get( 'EnableUploads' ), ]; @@ -308,7 +307,7 @@ */ public static function getStartupModulesUrl( ResourceLoaderContext $context ) { $rl = $context->getResourceLoader(); - $moduleNames = self::getStartupModules(); + $moduleNames = array_merge( self::getStartupModules(), self::getLegacyModules() ); $query = [ 'modules' => ResourceLoader::makePackedModulesString( $moduleNames ), diff --git a/includes/skins/Skin.php b/includes/skins/Skin.php index e5b9cb9..3e47583 100644 --- a/includes/skins/Skin.php +++ b/includes/skins/Skin.php @@ -163,8 +163,6 @@ 'content' => [ 'mediawiki.page.ready', ], - // modules that exist for legacy reasons - 'legacy' => ResourceLoaderStartUpModule::getLegacyModules(), // modules relating to search functionality 'search' => [], // modules relating to functionality relating to watching an article diff --git a/resources/src/mediawiki/mediawiki.js b/resources/src/mediawiki/mediawiki.js index 9d799db..a5417ff 100644 --- a/resources/src/mediawiki/mediawiki.js +++ b/resources/src/mediawiki/mediawiki.js @@ -1250,10 +1250,7 @@ registry[ module ].state = 'executing'; runScript = function () { - var script, markModuleReady, nestedAddScript, legacyWait, - // Expand to include dependencies since we have to exclude both legacy modules - // and their dependencies from the legacyWait (to prevent a circular dependency). - legacyModules = resolve( mw.config.get( 'wgResourceLoaderLegacyModules', [] ) ); + var script, markModuleReady, nestedAddScript; try { script = registry[ module ].script; markModuleReady = function () { @@ -1273,40 +1270,33 @@ nestedAddScript( arr, callback, i + 1 ); } ); }; + if ( $.isArray( script ) ) { + nestedAddScript( script, markModuleReady, 0 ); + } else if ( $.isFunction( script ) ) { + // Pass jQuery twice so that the signature of the closure which wraps + // the script can bind both '$' and 'jQuery'. + script( $, $, mw.loader.require, registry[ module ].module ); + markModuleReady(); - legacyWait = ( $.inArray( module, legacyModules ) !== -1 ) - ? $.Deferred().resolve() - : mw.loader.using( legacyModules ); - - legacyWait.always( function () { - if ( $.isArray( script ) ) { - nestedAddScript( script, markModuleReady, 0 ); - } else if ( $.isFunction( script ) ) { - // Pass jQuery twice so that the signature of the closure which wraps - // the script can bind both '$' and 'jQuery'. - script( $, $, mw.loader.require, registry[ module ].module ); - markModuleReady(); - - } else if ( typeof script === 'string' ) { - // Site and user modules are legacy scripts that run in the global scope. - // This is transported as a string instead of a function to avoid needing - // to use string manipulation to undo the function wrapper. - if ( module === 'user' ) { - // Implicit dependency on the site module. Not real dependency because - // it should run after 'site' regardless of whether it succeeds or fails. - mw.loader.using( 'site' ).always( function () { - $.globalEval( script ); - markModuleReady(); - } ); - } else { + } else if ( typeof script === 'string' ) { + // Site and user modules are legacy scripts that run in the global scope. + // This is transported as a string instead of a function to avoid needing + // to use string manipulation to undo the function wrapper. + if ( module === 'user' ) { + // Implicit dependency on the site module. Not real dependency because + // it should run after 'site' regardless of whether it succeeds or fails. + mw.loader.using( 'site' ).always( function () { $.globalEval( script ); markModuleReady(); - } + } ); } else { - // Module without script + $.globalEval( script ); markModuleReady(); } - } ); + } else { + // Module without script + markModuleReady(); + } } catch ( e ) { // This needs to NOT use mw.log because these errors are common in production mode // and not in debug mode, such as when a symbol that should be global isn't exported -- To view, visit https://gerrit.wikimedia.org/r/282505 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I54f087655e1cde1b8ff1ca5fe56e82f7f7d80965 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Krinkle <krinklem...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits