Right now we measure mwLoadStart in mediawiki-core/startup.js using Date#getTime (same as Date.now), but mwLoadEnd using mw.now (which uses navigationStart+performance.now in modern browsers).
The problem is that using mixing these two approaches produces inaccurate results.
For example:
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(); }; }() ); a = { d: Date.now(), p: now() }; b = { d: Date.now(), p: now() }; [a, b] > Array(2) > 0: Object > - d: 1482298290210 > - p: 1482298290232.265 > 1: Object > - d: 1482298290210 > - p: 1482298290232.27
It seems they are consistently off by the same amount within a single tab. In the above example, performance.now() was consistently 22ms later than Date.now() - which would cause things to appear 22ms slower than they really are (assuming end-start; where Date.now is used for start, and perf.now for end).
Browsing other random pages on various domains I get offsets varying from -1 to -90ms. And, at least in Google Chrome, the offset always gets worse as more time goes by (one is ticking faster than the other).
We should account for this offset or work around it.
Proposed solutions:
- Move mw.now() definition to startup.js and use it there for mwLoadStart (e.g. define as mwNow and assign to mw.now later).
- Or; Compute difference between Date.now() and mw.now() and subtract it when computing mwLoadEnd and mediaWikiLoadComplete in ext.navigationTiming.js