This is the 15th day of my participation in the August More Text Challenge. For details, see:August is more challenging

preface

IsInputPending () is a Scheduling API added by Facebook and Google to Chrome. It is also the first API that interrupts the operating system concept for web development. Developers can use this API to balance the priority between JS execution, page rendering, and user input, just as systems use interrupt scheduling cpus for IO input.

introduce

IsInputPending is a WICG incubation standard. Early Detection of Input Events (wicg.github. IO) is fully available on Chrome 87 and above, and is also available on Edge with the same kernel.

The API is designed by Facebook to weigh user input responses against page loading and script execution. Calling isInputPending() will return true if the browser has an input event that needs to be handled. It will detect all types of input events without passing any arguments, including DOM UI events such as button, mouse, wheel touch, or manually passing an array of arguments containing the event type.

Browser feature detection:

if(navigator.scheduling.isInputPending){
   // TODO
}
Copy the code

The background

As we all know, JavaScript is a single-threaded language, and browsers use an asynchronous, non-blocking event loop model to schedule JS tasks. During the execution of tasks, most tasks are done in the main thread, and for UI rendering and scripting operations, which are mutually exclusive, a single thread is undoubtedly very safe. However, the main thread often has to deal with user interaction. If the script takes a long time to execute, the user response cannot be processed in a timely way, resulting in page delays and user experience degradation.

In the past, we put some computation-intensive or high-delay tasks into the Web Worker for execution, and notify the main thread to obtain the results after the execution is completed. However, DOM cannot be operated in the Web Worker, and some UI operations such as animation drawing are also time-consuming operations, which can only be handled in the main thread.

At present, the best practice for JS scheduling is to divide JS tasks that need to be executed for a long time into pieces, and then put them into queues for execution in turn. After each execution, the control is returned to the browser. At this time, the browser will see whether there are events in the event queue that need to be responded to, and execute JS tasks again after all the responses are completed. This is similar to the time slice rotation algorithm in the operating system job scheduling, and each task can be handled fairly.

However, as you can see from the figure above, fast loading and fast response are not the same thing. If the JS execution takes too long, the browser will also have a delay in processing the event response: if the JS task is executed in chunks to improve response time, the page loading time will be longer.

The sample

Check for any input events

while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending()) {
    break;
  }
  let job = workQueue.shift();
  job.execute();
}
Copy the code

Check for specific input events

while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending(['mousedown'.'mouseup'.'keydown'.'keyup']) {break;
  }
  let job = workQueue.shift();
  job.execute();
}
Copy the code

conclusion

By reasonable use of isInputPending method, we can timely respond to user input during page rendering. In addition, when there is a long time consuming JS task to be executed, we can interrupt JS execution through isInputPending and return the control back to the browser to execute user response.

reference

  • Early detection of input events (wicg.github.io)
  • isInputPending: Facebook’s first browser API contribution – Facebook Engineering (fb.com)