First contribution to the browser API from Facebook

Original author: Nate Schloss, Andrew Comminos
  • Transfer

cover


Our position as the owners of a popular website - and our work in supporting the popular React platform - gives us unique opportunities and understanding of working with the browser that we want to use to solve the "queue" problem. As an active member of the Web Standards Community (W3C), we have been involved in a discussion of many innovations, including service workers and CSS-overscroll , but until recently, we never created our own initiatives to improve the web browser. In order to achieve a significant increase in productivity, a new API was proposed, which, as a result of close cooperation with our colleagues from Google Chrome, was provided for a trial version . Chrome v74 will includeisInputPending API , and can be used to improve both overall JavaScript execution time and event response time. This is just the first step to improving JavaScript planning on the web. We hope to get developer feedback and use them to create the final version of the API.


One of the most important performance indicators in the modern web is the time required to respond to a user event (clicking a button or entering into a field), with its full visualization. On Facebook, we share and measure events in four stages:


  • operating system receives data
  • actual start of processing
  • start displaying changes on screen in response to an event
  • processing is completed and the result is visualized

When we evaluated our most productive products, it was noticed that the waiting time in the queue gives the greatest delays. By queue is meant the time between when the user interacts with the page (for example, click or tap), and when the actual processing of the event begins. In some cases, this delay can be quite significant. Imagine that you click on the notification icon and then wait a minute before the button responds. Probably no one will wait for an answer.


Fast boot or quick response: choose one


There is a difficult trade-off between fast page loading and interactivity. If a website requires JavaScript, one option is to run it all in one block. But this can create problems. JavaScript mechanisms within web browsers are usually single-threaded, that is, they can only perform one operation per page at a time. In the case of loading the page, this means that if the user clicks on something, the browser must queue the click event until the entire JavaScript block is launched.


Like many other sites, we solve this problem by breaking JavaScript into small blocks. While the page is loading, we launch some JavaScript and then return control to the browser. Then the browser can check the input event queue and see if there is anything to handle. The browser can then return to running JavaScript blocks as they are added. This helps, but may cause other problems. Each time we return control to the browser, it takes some time to check the turn of the input events, process the events, and select the next JavaScript block. Thus, even though the browser responds to events faster, we still need to find a balance between the size of the code blocks and the frequency with which we are inferior to the browser. If we change controls too often, the page loads too slowly,


loadfast


If we run large JavaScript blocks, the browser can send user events with a long delay (above); if we run smaller blocks, the page takes longer to load (bottom).

isInputPending solution


When we first discovered delays in the queue, we turned to our colleagues in Chrome. We wanted to see how everything would look if we came up with a new download approach that would eliminate this compromise dilemma. After talking with them, we suggested isInputPending. The isInputPending API is the first to use the concept of interrupts for user events on the web.


Under the hood, isInputPending listens on the Chrome input queue on the compiler side to catch events before they are added to the main stream. Since this listening is performed outside the main thread, isInputPending calls do not consume a lot of computing resources and should be very fast. This allows developers to frequently call the API and maximize responsiveness.


As soon as we prepared this proposal, we turned to the W3C Web Performance Working Group and received the agreement of various browser vendors that our idea is worth exploring. In the future, we collaborated with our colleagues in Chrome, independently implemented a new API and sent the corresponding code fixes in Chrome. Thanks to the engineers from Chrome, we got trial patches that allow us to test changes and get feedback from developers before a full release. This version will allow us to understand how important this API is for developers and will determine our future conversations about this API with web browser providers. This is the first time that we have gone through all the stages of developing a web API, from discussing a proposal on a forum to passing code to a web browser.


How isInputPending Works


As the name implies, isInputPending tells you if there are events awaiting input. Developers can use this information while running JavaScript to decide whether they want to regain control of the browser. Used properly, isInputPending can completely eliminate the dilemma of fast loading and interactivity.


To work with the API is used navigator.scheduling.isInputPending(). Essentially, if the browser expects the event to be dispatched, this method returns true. When called without any arguments, all supported event types are checked. In addition, it is possible to manually specify a list of event types: mouse, wheel, touch, which should be checked for pending input.


Example: checking for any type of event


while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending()) {
    // прервать работу для обработки входных событий
    break;
  }
  let job = workQueue.shift();
  job.execute();
}

Example: checking for specific input events


while (workQueue.length > 0) {
  if (navigator.scheduling.isInputPending(['mousedown', 'mouseup', 'keydown', 'keyup'])) {
    // прервать работу для обработки события типа 'mousedown' или 'mouseup' или 'keydown' или 'keyup'
    break;
  }
  let job = workQueue.shift();
  job.execute();
}

What's next?


If the community feedback is positive, isInputPending may become fully available in Chrome. Then we can get rid of these noticeable delays in the queue and make work on the Internet faster and more flexible for people on our sites. For developers who also want to get rid of queue delays and improve interaction and download performance, a trial version will be available soon. Register here and share your opinion on the trial version as soon as it is available.


Chrome's isInputPending porting process is a new way to develop web standards on Facebook. We hope to continue to develop new APIs and increase our contribution to open source web browsers. In the future, we could potentially embed this API directly in React so that developers can take advantage of the API out of the box. In addition, isInputPending is now part of the great work of creating primitives for planning on the web. We look forward to continuing our partnership with Chrome. In the end, we hope to see browser tools that will allow developers to integrate more deeply into the browser task queue and even allow developers to understand browser priorities for various network requests and tasks.


Author Note


To try the new API you need:



Chrome v74

v74


Chrome v76 (develop)

v76

Only registered users can participate in the survey. Please come in.

How do you like the isInputPending API?

  • 45.7% First time I hear, try 27
  • 33.8% Not tried, not interesting 20
  • 5% Tried, functional for saving on matches 3
  • 0% I tried, this is the next step in the development of the web 0
  • 0% Actively use in projects 0
  • 15.2% I am writing on WordPress and I do not care about your optimizations 9

Also popular now: