diff options
Diffstat (limited to 'www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js')
-rw-r--r-- | www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js b/www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js new file mode 100644 index 00000000..650092bd --- /dev/null +++ b/www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js @@ -0,0 +1,52 @@ +( function ( mw ) { + var maxBusy = 50; + + mw.requestIdleCallbackInternal = function ( callback ) { + setTimeout( function () { + var start = mw.now(); + callback( { + didTimeout: false, + timeRemaining: function () { + return Math.max( 0, maxBusy - ( mw.now() - start ) ); + } + } ); + }, 1 ); + }; + + /** + * Schedule a deferred task to run in the background. + * + * This allows code to perform tasks in the main thread without impacting + * time-critical operations such as animations and response to input events. + * + * Basic logic is as follows: + * + * - User input event should be acknowledged within 100ms per [RAIL]. + * - Idle work should be grouped in blocks of upto 50ms so that enough time + * remains for the event handler to execute and any rendering to take place. + * - Whenever a native event happens (e.g. user input), the deadline for any + * running idle callback drops to 0. + * - As long as the deadline is non-zero, other callbacks pending may be + * executed in the same idle period. + * + * See also: + * + * - <https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback> + * - <https://w3c.github.io/requestidlecallback/> + * - <https://developers.google.com/web/updates/2015/08/using-requestidlecallback> + * [RAIL]: https://developers.google.com/web/fundamentals/performance/rail + * + * @member mw + * @param {Function} callback + * @param {Object} [options] + * @param {number} [options.timeout] If set, the callback will be scheduled for + * immediate execution after this amount of time (in milliseconds) if it didn't run + * by that time. + */ + mw.requestIdleCallback = window.requestIdleCallback ? + window.requestIdleCallback.bind( window ) : // Bind because it throws TypeError if context is not window + mw.requestIdleCallbackInternal; + // Note: Polyfill was previously disabled due to + // https://bugs.chromium.org/p/chromium/issues/detail?id=647870 + // See also <http://codepen.io/Krinkle/full/XNGEvv> +}( mediaWiki ) ); |