( 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: * * - * - * - * [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 }( mediaWiki ) );