summaryrefslogtreecommitdiff
path: root/www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js')
-rw-r--r--www/wiki/resources/src/mediawiki/mediawiki.requestIdleCallback.js52
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 ) );