resourceloader: Simplify mwLoadEnd hook implementation

In addition to the high overhead of $.Deferred per-module in
mw.loader.using(), this was also using $.when() and another
Deferred in catch() for casting.

The handler for marking mwLoadEnd needs a Promise in our fallback
for compatibility with the original using() call. But the code
within our fallback does not need to use N promises, for that
we can simply use a counter that we decrement, given we only need
to worry about completion.

So basically, use `Deferred#always(callback)`
instead of `Deferred.catch(=>Defered().resolve)).then(callback)`.

This is in preparation for moving the code to NavigationTiming.

Change-Id: I20514d3fe680fc9384a0f7ce0880652970d86856
This commit is contained in:
Timo Tijhof 2018-05-07 22:57:40 +01:00 committed by Krinkle
parent 99a57ca021
commit 9d2e43df75

View file

@ -2813,23 +2813,28 @@
* @member mw.hook
*/
$( function () {
var loading, modules;
modules = mw.loader.getModuleNames().filter( function ( module ) {
// Get a list of modules currently in loading state
var modules = mw.loader.getModuleNames().filter( function ( module ) {
return mw.loader.getState( module ) === 'loading';
} );
// 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( modules ).catch( function () {
var all = modules.map( function ( module ) {
return mw.loader.using( module ).catch( function () {
return $.Deferred().resolve();
} );
// Wait for them to complete loading (regardles of failures). First, try a single
// mw.loader.using() call. That's efficient, but has the drawback of being rejected
// upon first failure. Fall back to tracking each module separately. We usually avoid
// that because of high overhead for that internally to mw.loader.
mw.loader.using( modules ).catch( function () {
return $.Deferred( function ( deferred ) {
var i, count = modules.length;
function decrement() {
count--;
if ( count === 0 ) {
deferred.resolve();
}
}
for ( i = 0; i < modules.length; i++ ) {
mw.loader.using( modules[ i ] ).always( decrement );
}
} );
return $.when.apply( $, all );
} );
loading.then( function () {
} ).then( function () {
if ( window.performance && performance.mark ) {
performance.mark( 'mwLoadEnd' );
}