Musings of an open source hacker

Main menu

Post navigation

Electrolysis: A tale of tab switching and themes

Electrolysis (“e10s”) is a project by Mozilla to bring Firefox from its traditional single-process roots to a modern multi-process browser. The general idea here is that with modern computers having multiple CPU cores, we should be able to make effective use of that by parallelising as much of our work as possible. This brings benefits like being able to have a responsive user interface when we have a page that requires a lot of work to process, or being able to recover from content process crashes by simply restarting the crashed process.

However, I want to touch on one particular aspect of e10s that works differently to non-e10s Firefox, and that is the way tab switching is handled.

Currently, when a user switches tabs, we do the operation synchronously. That is, when a user requests a new tab for display, the browser effectively halts what it’s doing until it is in a position to display that tab, at which point it will switch the tab. This is fine for the most part, but if the browser gets bogged down and is stuck waiting for CPU time, it can take a jarring amount of time for the tab to be switched.

With e10s, we are able to do better. In this case, we are able to switch tabs asynchronously. When the user requests a new tab, we fire off the request to the process that handles processing that tab, and wait for a message back from that process that says “I’m ready to be displayed now”, and crucially we do not switch the selected tab in the user interface (the “chrome”) until we get that message. In most cases, this should happen in under 300ms, but if we hit 300ms and we still haven’t received the message, we switch the tab anyway and show a big spinner where the tab content would be to indicate that we’re still waiting for the initial content to be ready for display.

Unfortunately, this affects themes. Basically, there’s an attribute on the tab element called “selected” which is used by the CSS to style the tab accordingly. With the switch to asynchronous tab switching, I added a new attribute, “visuallyselected”, which is used by the CSS to style the tab. The “selected” attribute is now used to signify a logical selection within the browser.

We thought long and hard about making this change, and concluded that this was the best approach to take. It was the least invasive in terms of changing our existing browser code, and kept all our test assumptions valid (primarily that “selected” is applied synchronously with a tab switch). The impact on third party themes that haven’t been updated is that if they’re styled off the “selected” attribute, they will immediately show a tab switch but can show the old tab’s content for up to 300ms until either the new tab’s content is ready, or the spinner is shown. Using “visuallyselected” on non-e10s works fine as well, because we now apply both the “selected” and “visuallyselected” attributes on the tab when it is selected in the non-e10s case.

Have we considered saving a bitmap of each tab in-process so we could at least show something resembling what the user expected, perhaps a dimmed version, while we wait? I’m on a fairly fast machine but get the spinner a lot, and I find it jarring each time.

The problem here is that we absolutely should not change the selected tab in the tab strip at the top of the window unless the content area matches what’s being shown in the tab strip. If content isn’t ready, then flipping the tab bar immediately does nothing except create a mismatch visually which is jarring to the user, as the old content will still be visible. We’re not arbitrarily gating the switch process (we’d love to be able to switch immediately in every circumstance!) but rather ensuring that visually all the switch happens at the same time.

As development on e10s matures, we’re going to start concentrating more and more on optimisation, but for now we’re mostly concerned with correctness.

In terms of allowing for a switch to occur more quickly, we’ve been investigating various options such as caching a bitmap or rendering the page background colour as soon as possible. Any of these solutions would result in the signal from content to say “I’m ready, switch the tab”, so the existing mechanism would still be relevant. We just need to be able to deal with pathological cases where we hit the 300ms timeout.

For some non-sdk-based addons, it is hard to support both versions of Firefox 38 (current ESR) and Firefox 41-, because Firefox 38 doesn’t know “visuallyselected” attribute. So I’ve released a helper library to backport the attribute for old versions of Firefox. I think it will help addon authors who bothered by this change.

Wouldn’t it make more sense for backwards compatibility to have the final state be named [selected] and create a new name for the in-process selection like [selecting] or [selectionpending] ? It’s not even semantically correct to say that a tab that is hung is selectED as in past-tense done and finished. I don’t even know why you would want to style a tab that is not fully selected beyond the normal “hover” style… except perhaps to display the “connecting” first-stage throbber maybe.