Skip to main content
PC
June 1, 2017

Improving input responsiveness in Microsoft Edge



As the web becomes more interactive, web pages are becoming increasingly reliant on JavaScript for core functionality, such as input, rendering, layout, and composition. As more and more of this core functionality moves to the client side, it becomes imperative for browsers to adopt smart scheduling mechanisms to ensure that JavaScript workloads are processed in an efficient manner.

With EdgeHTML 15 and the Windows 10 Creators Update, Microsoft Edge takes a big leap forward in how it schedules JavaScript work, leading to noticeable improvements in the usability, responsiveness, and performance of the modern web. In this post, we’ll share some behind-the-scenes details on how the EdgeHTML engine works, as well as the huge impact these improvements have had on making the browser feel faster and more responsive.

Timers: death by a thousand cuts

The web is surprisingly complex when it comes to task management. Rather than running one long JavaScript operation, most websites tend to execute a series of small-to-medium-sized operations that add up over time: event listeners, timeouts, Promises, and various other asynchronous tasks.

Even on a page that looks relatively quiet, below the surface there may be quite a lot of work going on. News and content sites that rely on advertisements, analytics trackers, and scroll listeners are often a good example of this. For instance, here’s a sample site illustrating some problems we often see on poorly optimized sites in the wild:

While this page is loading, and even well after it’s “settled,” there is still an enormous amount of work going on under the hood. A web page such as this one may make network requests for additional resources, or it may call setTimeout to queue a task for the next “tick” of the event loop. Each of these callbacks can then schedule other timeouts and network requests, starting the process anew. It’s the browser’s job to coordinate these tasks, and to ensure that they’re processed correctly along with event listeners, Promises, and any other work in accordance with the HTML5 event loop spec.

Where it gets complicated is with input tasks. As noted in “Scrolling on the web,” Microsoft Edge already offers best-in class scrolling performance, because the vast majority of scrolling devices can be handled on a background thread. This means that these input methods are unaffected by a page that schedules lots of JavaScript work, so scrolling on a mousewheel, touchpad, or touchscreen should always feel smooth.

Due to hardware limitations, though, some scrolling methods (such as using the keyboard) are still processed on the UI thread. This is also true of many other website interactions, such as clicking links and typing into a form field. And since these input events must be processed on the same thread that handles the JavaScript event loop, this is where things can go south very quickly.

Input blocking: the “Is this page broken?” effect

You’re probably familiar with this experience: you load a page, and the content appears on the screen, so you believe you can start interacting with it. However, if you try to click a link, several seconds pass by without anything happening. Or you might try to scroll using your keyboard’s up and down arrows, but the page moves at a glacial pace, or it doesn’t even scroll at all.

This often occurred in previous releases of Microsoft Edge on pages that queue up a lot of setTimeouts or other callbacks. This is because our scheduling system didn’t prioritize input over regular JavaScript tasks, meaning that all scheduled timeouts had to be processed on the main thread before any input could be received.

Beginning with EdgeHTML 15, Microsoft Edge now allows input events to “cut in line” ahead of JavaScript work, using a technique called input prioritization. With this new scheduler in place, input events can be handled nearly instantly, even if the page has queued up a large backlog of setTimeout operations.

The impact on some pages can be startling. We’ve already heard feedback from Windows Insiders that the performance improvement of Microsoft Edge is “night and day,” thanks to the new ability to immediately scroll and immediately click links. No more waiting multiple agonizing seconds for a JavaScript-heavy page to finish its loading process!

For example, the “news site” below is doing several seconds’ worth of work on the UI thread while it’s loading. If you try to click the first link during that load, the navigation may be blocked, because mouse input is not being prioritized.

As of EdgeHTML 15, however, Microsoft Edge now prioritizes the click event ahead of other work, meaning that the next page loads nearly instantly:

Here’s another example showing the impact on scrolling. This page, like the sample news site, is running several setTimeouts in the background, which can interfere with keyboard scrolling:

As of EdgeHTML 15, the page remains scrollable with the keyboard, even while the setTimeouts are being processed. This reduces a common source of blocked or laggy scrolling on very active web pages.

Giving priority to the user

To understand what EdgeHTML 15 is doing under the hood to achieve this performance boost, let’s whip up a quick metaphor. Note that, as is often the case, the actual implementation is a bit more complex, but we’ll simplify a bit in the interests of clarity.

With a little help from some illustrations courtesy of Rachel Nabors, we can visualize the way tasks are processed in a web page by imagining a trendy club with a lineup of eager customers stretching out around the block, and a stern bouncer letting in only one client at a time.

Illustration showing a club, "The UI Thread." In front of the club, a long queue of customers are lined up, labelled "JS, Style, Layout," etc.

In the pre-Creators Update implementation, everybody had to get into the same line: JavaScript timers, layout and style updates, and input events alike. Worse, since JavaScript timers can queue their own timers, these could actually cut in line ahead of other events, if the original timer took so much time to complete that the next timer was now “scheduled” to run.

In our club metaphor, this would be like a particularly inconsiderate patron calling their friend on the phone to say, “No problem, I can hold your place in the line. I’ll just tell the bouncer you’re on your way!” And then, insult of insults, the bouncer would actually allow them to hold up the entire line, waiting for their friend to show! All the while, the poor input event is still waiting at the back of the line.

As of the Creators Update, though, this lineup has been completely redesigned. Rather than maintaining a single queue to process all events, there is now a priority queue for input events. This is as if our club added a special VIP line, allowing high-profile guests to get in ahead of the thoughtless patron trying to call their buddy.

Illustration of a character dressed as User Input, with mouse pointers for earrings, skipping the UI Thread line in a separate "VIP" line.

This is a much better system, because input events fundamentally deserve higher priority than any other operations on a web page. Ultimately, the user is the king or queen of their browser, and whatever work a website is trying to complete is less important than what the user wants to accomplish. Even if a page is very busy running JavaScript timers, any input from the user’s mouse or keyboard should be considered top priority.

Prioritizing the browser UI itself over web content

In addition to creating a “fast lane” for user input to web pages, another improvement we made in the Creators Update was to make another special queue for input to the browser UI itself.

You can imagine that, if input is shared between a web page and the browser frame – i.e. the URL bar, tabs, favorite button, etc. – then a misbehaved web page could potentially render the entire browser unresponsive. For some web content, this was the situation before the Creators Update, but now Microsoft Edge is more intelligent about handling browser UI input separately from web page input.

In this example, we’re using crashmybrowser.com, a wonderful site that does exactly what you’d think. In one of the site’s tests, we can create a “fork bomb,” where a timeout spawns two more timeouts, each of which spawns two more timeouts, and so on, causing the page to become completely hung. Prior to the Creators Update, this kind of unrelenting JavaScript assault would prevent users from being able to close the tab or to open a new one, since browser UI input was not handled any separately from other kinds of input.

In the Creators Update, however, browser UI input has been given special priority, allowing the user to close a misbehaving tab without waiting for it to respond. Note that this input is handled even earlier than the in-page user input. For instance, in the case of an infinite loop (another fun option on crashmybrowser.com), input to the web page itself would never be handled, but input to the browser UI itself should be able to respond regardless of what the web page is up to.

Circling back to our trendy club example, this special treatment of browser UI input would be like a hidden side entrance to the club, only available to members of the band and their entourage. While VIPs may get first dibs to line up into the club, the band is even more important! So they should be able to fast-track into the green room.

Illustration showing a band member entering the club through a side door, labelled "Browser Only"

Real users see web content responsiveness improvements

To see the impact of this work on web content responsiveness, we can look at aggregated telemetry from EdgeHTML 15 Windows Insider devices, comparing November builds (before input prioritization was implemented) to March builds (after it was introduced). For interactions, we broadly bucket responsiveness into “great” sessions (<300ms), “poor” sessions (300-1000ms), and “terrible” sessions (>1000ms).

Bar chart showing input responsiveness in EdgeHTML 15 November (before) versus March (after). Microsoft Edge has increased the number of “great” sessions from 88.71% to 95.53%, while decreasing the number of “poor” sessions from 5.68% to 3% and the number of “terrible” sessions from 5.61% to 1.46%.

As you can see in the above chart, Microsoft Edge has increased the number of “great” sessions from 88.71% to 95.53%, while decreasing the number of “poor” sessions from 5.68% to 3% and the number of “terrible” sessions from 5.61% to 1.46%.

The confirms that Microsoft Edge users are seeing the benefits of this input prioritization effort firsthand. For most sites, users have a great session.  However, when a site is bad, it can be a terrible experience. Aggregated Windows telemetry clearly shows that the input prioritization improvements in the Creators Update have significantly reduced the number of less-than-great sessions on heavy websites.

Conclusion

All these input changes serve one unique purpose: to put users in control of their browsing. Regardless of what a web page is trying to accomplish, the user should be able to interact with their browser and manage their tabs, scroll their content, and navigate to new pages as fast as their fingers can move. With these improvements in the Creators Update, Microsoft Edge users will enjoy a faster, more fluid, and more responsive browser.

As Bret Victor famously said, “creators need an immediate connection to what they’re creating.” This is true not only of creators but also of web surfers: when you type or click, the web page should immediately respond. This responsiveness helps maintain the most immersive aspects of the web, and creates a strong visceral connection between the user and their browser. Immediate feedback is crucial not only for creative flow, but also for seamless web surfing.  With the Creators Update, Microsoft Edge has made a big step in achieving that vision.

Nolan Lawson, Program Manager, Microsoft Edge
Todd Reifsteck, Senior Program Manager, Microsoft Edge
Rachel Nabors, Program Manager, Microsoft Edge