From: Timo Tijhof Date: Fri, 26 Aug 2016 04:51:01 +0000 (-0700) Subject: mw.loader: Make 'mwLoadEnd' less expensive with a single using() X-Git-Tag: 1.31.0-rc.0~5348^2~2 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/ajouter.php?a=commitdiff_plain;h=2bdd56e89334d85c48753b0052b0a94689dd584b;p=lhc%2Fweb%2Fwiklou.git mw.loader: Make 'mwLoadEnd' less expensive with a single using() 20-30ms before this patch, ~2ms after this patch (MacBookPro, Chrome 52). The creation of 100s of Deferred objects, $.when() tracking them all, and bubbling up the completion took 20-30ms. This is quite expensive. Optimise by using a single deferred first. A module reaching state 'missing' or 'error' is very rare. Change-Id: I90eea4bfe8fe6d85c395d9d0868bbde482c4a703 --- diff --git a/resources/src/mediawiki/mediawiki.js b/resources/src/mediawiki/mediawiki.js index af37162cbe..7ceb5fe9ee 100644 --- a/resources/src/mediawiki/mediawiki.js +++ b/resources/src/mediawiki/mediawiki.js @@ -2693,14 +2693,18 @@ var loading = $.grep( mw.loader.getModuleNames(), function ( module ) { return mw.loader.getState( module ) === 'loading'; } ); - // In order to use jQuery.when (which stops early if one of the promises got rejected) - // cast any loading failures into successes. We only need a callback, not the module. - loading = $.map( loading, function ( module ) { - return mw.loader.using( module ).then( null, function () { - return $.Deferred().resolve(); + // We only need a callback, not any actual module. First try a single using() + // for all loading modules. If one fails, fall back to tracking each module + // separately via $.when(), this is expensive. + loading = mw.loader.using( loading ).then( null, function () { + var all = $.map( loading, function ( module ) { + return mw.loader.using( module ).then( null, function () { + return $.Deferred().resolve(); + } ); } ); + return $.when.apply( $, all ); } ); - $.when.apply( $, loading ).then( function () { + loading.then( function () { mwPerformance.mark( 'mwLoadEnd' ); mw.hook( 'resourceloader.loadEnd' ).fire(); } );