Many times there may be some non-essential, low-priority Javascript code to be executed. You would like it to be executed, but instantaneous execution is not your primary concern. A good example can be sending analytics data to the server. You just want to send the data to the server. You are okay if the browser sends the data to the server in its "free" time, which may be milliseconds or seconds later.
Performing low-priority work in the browser was not possible a few years ago. But with the introduction of the new requestIdleCallback method, this is possible.
The requestIdleCallback method will execute a piece of code when the browser is sitting idle. Because the task is performed in the browser's "free" time, the performance of the webpage is not impacted.
Using the requestIdleCallback Method
Scheduling a task in the most basic way is to call the requestIdleCallback method it with a callback function parameter. The callback contains the code to perform your background task.
var handle = requestIdleCallback(function() {
// code to perform the task
});
var handle = requestIdleCallback(performTask);
function performTask() {
// code to perform the task
}
The return value is a handle to the scheduled task. This handle may be helpful if you want the cancel out the task later.
Knowing How Much Free Time is Left
requestIdleCallback performs the task in the browser's idle time — you can even get access to that specific amount of time.
The callback function receives a IdleDeadline object as its parameter. This object contains a timeRemaining() method that gives the time (in milliseconds) left in the current idle period. This is 0 if the idle period is over. This function can be called repeatedly to get its latest value and check whether there is time left to perform more background activities.
requestIdleCallback(function(deadline) {
var time_left = deadline.timeRemaining();
// code to perform the task
// code executed
// check if time left to execute more code
time_left = deadline.timeRemaining();
if(time_left > 0) {
// more code
}
else {
// no time left to execute this code
// use requestIdleCallback again to schedule the code execution
}
});
The reason to give access to the amount of idle time left is for better planning so that webpage performance is not impacted. For example if the task is quite long, you can divide its execution to be performed in a series of idle periods instead of executing in one single go and risk the webpage performance.
In the worst case if your task exceeds the given idle time, browser will not stop your task. The complete code will be still be executed, but obviously performance may be impacted (for example page may freeze).
Making Sure the Background Task is Performed
Sometimes the case may be that the background task is low-priority, but it definitely needs to be executed. At max you can delay the task by some time.
For such cases requestIdleCallback accepts a second parameter through which you can set the timeout period. Browser must invoke the callback function within that timeout period.
When the timeout exceeds and the browser invokes the callback, the didTimeout property of the IdleDeadline object will be set to true. Your code should handle the case appropriately and should execute the code rightaway. Performance may be impacted but the task is performed nevertheless.
// task can be delayed by 5 seconds at max
requestIdleCallback(function(deadline) {
if(deadline.timeRemaining() > 0 || deadline.didTimeout == true) {
// execute code
}
}, { timeout: 5000 });
Cancelling the Task
The task can be cancelled with the cancelIdleCallback method. It takes the handle of the task created as the parameter.
var handle = requestIdleCallback(function() {
// code to perform the task
});
// cancel the scheduled task
cancelIdleCallback(handle);