From e7d3bce00f418b1f2bc7732aa946b7c9d7c563d0 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Thu, 9 Feb 2017 21:46:37 +0000 Subject: [PATCH] resourceloader: Use perf.now() for mediaWikiLoadStart in startup.js Currently we're using 'new Date' which is less accurate for high accuracy performance measures. On top of that, we are actually using performance.now() in Navigation Timing to measure mediaWikiLoadEnd, and subsequently relating it to mediaWikiLoadStart to produce mediaWikiLoadComplete. Mixing Date and performance.now produces inaccurate results since the two are usually not in sync. See T153819 for further details. Solve this by moving the polyfil to startup.js instead. Also add a basic unit test for mw.now(). Bug: T153819 Change-Id: Ib44538155aa9ba432ec4c58b09ead5333a3a942d --- .eslintrc.json | 1 - resources/src/mediawiki/mediawiki.js | 11 ++++------- resources/src/startup.js | 16 ++++++++++++---- .../suites/resources/mediawiki/mediawiki.test.js | 9 +++++++++ 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 044dd7202d..98d0f10fa9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,7 +9,6 @@ "require": false, "module": false, "mediaWiki": false, - "mwPerformance": false, "OO": false }, "rules": { diff --git a/resources/src/mediawiki/mediawiki.js b/resources/src/mediawiki/mediawiki.js index fceeb64c4b..4df2df7985 100644 --- a/resources/src/mediawiki/mediawiki.js +++ b/resources/src/mediawiki/mediawiki.js @@ -8,6 +8,7 @@ * @singleton */ +/* global mwNow */ /* eslint-disable no-use-before-define */ ( function ( $ ) { @@ -524,13 +525,8 @@ * * @return {number} Current time */ - now: ( function () { - var perf = window.performance, - navStart = perf && perf.timing && perf.timing.navigationStart; - return navStart && typeof perf.now === 'function' ? - function () { return navStart + perf.now(); } : - function () { return +new Date(); }; - }() ), + now: mwNow, + // mwNow is defined in startup.js /** * Format a string. Replace $1, $2 ... $N with positional arguments. @@ -2785,6 +2781,7 @@ return $.when.apply( $, all ); } ); loading.then( function () { + /* global mwPerformance */ mwPerformance.mark( 'mwLoadEnd' ); mw.hook( 'resourceloader.loadEnd' ).fire(); } ); diff --git a/resources/src/startup.js b/resources/src/startup.js index 20818d2656..deb280a8f1 100644 --- a/resources/src/startup.js +++ b/resources/src/startup.js @@ -6,11 +6,19 @@ /* global mw, $VARS, $CODE */ -// eslint-disable-next-line no-unused-vars -var mediaWikiLoadStart = ( new Date() ).getTime(), - mwPerformance = ( window.performance && performance.mark ) ? performance : { +var mwPerformance = ( window.performance && performance.mark ) ? performance : { mark: function () {} - }; + }, + // Define now() here to ensure valid comparison with mediaWikiLoadEnd (T153819). + mwNow = ( function () { + var perf = window.performance, + navStart = perf && perf.timing && perf.timing.navigationStart; + return navStart && typeof perf.now === 'function' ? + function () { return navStart + perf.now(); } : + function () { return +new Date(); }; + }() ), + // eslint-disable-next-line no-unused-vars + mediaWikiLoadStart = mwNow(); mwPerformance.mark( 'mwLoadStart' ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js index bac8274fef..65b726312c 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js @@ -64,6 +64,15 @@ ); } ); + QUnit.test( 'mw.now', function ( assert ) { + assert.equal( typeof mw.now(), 'number', 'Return a number' ); + assert.equal( + String( Math.round( mw.now() ) ).length, + String( +new Date() ).length, + 'Match size of current timestamp' + ); + } ); + QUnit.test( 'mw.Map', function ( assert ) { var arry, conf, funky, globalConf, nummy, someValues; -- 2.20.1