]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - resources/src/mediawiki/mediawiki.requestIdleCallback.js
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / resources / src / mediawiki / mediawiki.requestIdleCallback.js
diff --git a/resources/src/mediawiki/mediawiki.requestIdleCallback.js b/resources/src/mediawiki/mediawiki.requestIdleCallback.js
new file mode 100644 (file)
index 0000000..650092b
--- /dev/null
@@ -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 ) );