Module storage: randomly choose between Function and $.globalEval
authorOri Livneh <ori@wikimedia.org>
Tue, 10 Dec 2013 06:35:37 +0000 (22:35 -0800)
committerOri Livneh <ori@wikimedia.org>
Tue, 10 Dec 2013 07:00:02 +0000 (23:00 -0800)
V8 disables certain optimizations for eval()'d code because scope resolution is
tricky. The same is not true for code compiled via Function(), which always
runs in global scope. Let's see if Function() is faster.

This patch makes ResourceLoader randomly use either Function() or $.globalEval.
The choice is recorded in a boolean `useFunction` property on mw.loader.store
so its value can be logged with load timing measurements. The logging will be
done in WikimediaEvents.

Bug: 58259
Change-Id: I7183778cb65c421ee19dcd61ee1dc0085f86bf10

resources/mediawiki/mediawiki.js

index 724ca5e..840a071 100644 (file)
@@ -1269,7 +1269,12 @@ var mw = ( function ( $, undefined ) {
                                                        }
                                                        return true;
                                                } );
-                                               $.globalEval( concatSource.join( ';' ) );
+                                               if ( mw.loader.store.useFunction ) {
+                                                       /* jshint -W054 */
+                                                       new Function( concatSource.join( ';' ) )();
+                                               } else {
+                                                       $.globalEval( concatSource.join( ';' ) );
+                                               }
                                        }
 
                                        // Early exit if there's nothing to load...
@@ -1816,6 +1821,7 @@ var mw = ( function ( $, undefined ) {
                                                        raw = localStorage.getItem( mw.loader.store.getStoreKey() );
                                                        // If we get here, localStorage is available; mark enabled.
                                                        mw.loader.store.enabled = true;
+                                                       mw.loader.store.useFunction = !!Math.floor( Math.random() * 2 );
                                                        data = JSON.parse( raw );
                                                        if ( data && typeof data.items === 'object' && data.vary === mw.loader.store.getVary() ) {
                                                                mw.loader.store.items = data.items;