Have you been using Firefox Nightly and seen this big annoying spinner?
I hate that thing. I hate it.
And while we’re working on making the spinner itself less ugly, I’d like to eliminate, or at least reduce its presence to the absolute minimum.
How do I do that? Well, first, know your enemy.
What does it even mean?
That big spinner means that the graphics part of Gecko hasn’t given us a frame yet to paint for this browser tab. That means we have nothing yet to show for the tab you’ve selected.
In the single-process Firefox that we ship today, this graphics operation of preparing a frame is something that Firefox will block on, so the tab will just not switch until the frame is ready. In fact, I’m pretty sure the whole browser will become unresponsive until the frame is ready.
With Electrolysis / multi-process Firefox, things are a bit different. The main browser process tells the content process, “Hey, I want to show the content associated with the tab that the user just selected”, and the content process computes what should be shown, and when the frame is ready, the parent process hears about it and the switch is complete. During that waiting time, the rest of the browser is still responsive – we do not block on it.
So there’s this window of time where the tab switch has been requested, and when the frame is ready.
During that window of time, we keep showing the currently selected tab. If, however, 300ms passes, and we still haven’t gotten a frame to paint, that’s when we show the big spinner.
So that’s what the big spinner means – we waited 300ms, and we still have no frame to draw to the screen.
How bad is it?
I suspect it varies. I see the spinner a lot less on my Windows machine than on my MacBook, so I suspect that performance is somehow worse on OS X than on Windows. But that’s purely subjective. We’ve recently landed some Telemetry probes to try to get a better sense of how often the spinner is showing up, and how laggy our tab switching really is. Hopefully we’ll get some useful data out of that, and as we work to improve tab switch times, we’ll see improvement in our Telemetry numbers as well.
Where is the badness coming from?
This is still unclear. And I don’t think it’s a single thing – many things might be causing this problem. Anything that blocks up the main thread of the content process, like slow JavaScript running on a web-site, can cause the spinner.
I also seem to see the spinner when I have “many” tabs open (~30), and have a build going on in the background (so my machine is under heavy load).
Maybe we’re just doing things inefficiently in the multi-process case. I recently landed profile markers for the Gecko Profiler for async tab switching, to help figure out what’s going on when I experience slow tab switch. Maybe there are optimizations we can make there.
One thing I’ve noticed is that there’s this function in the graphics layer, “ClientTiledLayerBuffer::ValidateTile”, that takes much, much longer in the content process than in the single-process case. I’ve filed a bug on that, and I’ll ask folks from the Graphics Team this week.
How you can help
UPDATE (June 1, 2015): Getting profiles from Windows is currently broken because the symbol server appears to be busted. Any profiles from Windows machines will be useless until this bug is fixed. Alternatively, set profiler.symbolicationUrl to http://symbolapi.mocotoolsstaging.net in about:config.
If you’d like to help me find more potential causes, Profiles are very useful! NOTE – I don’t mean “user profiles”, as in, your bookmarks / customizations / history, etc, in the profile folder. I don’t mean this thing. I mean a performance profile.
A performance profile is a read-out of everything that Firefox / Gecko is doing over a particular span of time. When the profiler is running, Firefox / Gecko will record where the process is in the stack every 1ms or so. It’ll also record information about how long since it’s serviced the event loop, which helps us find jank.
To help, grab the Gecko Profiler add-on, make sure it’s enabled, and then dump a profile when you see the big spinner of doom. The interesting part will be between two markers, “AsyncTabSwitch:Start” and “AsyncTabSwitch:Finish”. There are also markers for when the parent process displays the spinner – “AsyncTabSwitch:SpinnerShown” and “AsyncTabSwitch:SpinnerHidden”. The interesting stuff, I believe, will be in the “Content” section of the profile between those markers. Here are more comprehensive instructions on using the Gecko Profiler add-on.
And here’s a video of me demonstrating how to use the profiler, and how to attach a profile to the bug where we’re working on improving tab switch times:
And here’s the link I refer you to in the video for getting the add-on.
So hopefully we’ll get some useful data, and we can drive instances of this spinner into the ground.
I’d really like that.
Hey Mike, thanks for working on this. The “Big Tab Spinner” is showing up here all the time. Even for most tab switches (!), it shows up.
This is on Linux, 64 bit, 32 GB RAM, 4 core AMD CPU, self-compiled.
Reproduction:
Open 10 windows with 10 tabs each
Open a new window
Go to a news page or Google result page, wait until it’s fully loaded
Open a few pages in the background by middle-clicking on links
Go to tab. Big Tab Spinner. Wait 3-4 seconds. Page appears.
Go back to tab with the original page. Big Tab Spinner. Wait 2-3 seconds. Page appears.
Go back to tab from 2 steps above. Again Big Tab Spinner. Wait 3-4 seconds. Page appears.
This obviously makes e10s unusable. Firefox has gotten noticeably sluggish and slow with e10s. I expected the opposite.
@BenB:
Do you see the same behaviour with all of your add-ons disabled (Don’t use safe mode to test this – that’ll disable e10s too. You must manually disable your add-ons.)
-Mike
I have the following addons enabled: Adblock Plus, Greasemonkey, DOMI, cliget.
Due to the 100 pages I have open, I am reluctant to restart the browser. I think the addons are fairly representative for many users, though. (Apart from cliget, which just adds a context menu item.)
Ben
@BenB:
I understand. And where add-ons are causing issues, we should investigate.
I’m, however, primarily concerned about the case where Firefox is causing the spinner, out-of-the-box. Performance problems caused by add-ons is something separate, I think.
-Mike
The worst part about the spinner is that, if you have many tabs open and one is causing the jank, they will all then have the spinner as you switch back between each of them. Because e10s only splits chrome from content and not tab from tab, that’s going to be a big contributor to the jank.
Excitingly, I’ve bumped up dom.ipc.processCount’s value to more than the number of tabs I have open, restarted Firefox for the tabs to be split between the processes, and I don’t really ever see the spinner anymore.
Happens to me usually once or twice in a day. Can’t Exactly pinpoint what site causes this.
Sometime OVER closing and opening Facebook tabs or switching a lot between different reddit and facebook tabs leads me to this. And yes that GIF does represent the frustration.
I have to close and restart the browser for it to go away.
Nowadays im getting the tab has crashed more often over all my tabs after some time of browsing.
I hope you get the crash reports, it says when i displays the message to restore tabs.
Add-ons: HTitle; happens without it also
Fedora Linux 21; Nightly 40
Thank you for working on this.
And could you please mention where we should post this Gecko Profile info? and is it safe to share? Like no private info?
To be honest, I’m not sure if you’re conclusion “In fact, I’m pretty sure the whole browser will become unresponsive until the frame is ready.” is correct without seeing any data. It might be the case that I haven’t noticed any lags before, but nowadays I see the spinner every time I switch a tab. This might be fully visually though (in the meaning that something happens but it’s not ready yet vs. “this is just a minor lag, I’m okay with it”).
I’ll certainly use the addon to provide more data.
@Michael
To be clear, what I meant was that in the single-process case (the conditions under which our release version of Firefox currently ships), waiting for a frame to paint blocks the main thread, and will cause the browser to be come unresponsive. This is fact.
With multi-process Firefox, we do not block the main thread of the main browser process. Instead, the spinner means that the main thread of the content process is blocked or busy somehow.
Should I care that main thread is blocked if I anyway changing the tab? Till now I have not noticed any problems changing tabs. But tried out Nightly and the throbber appeared every time. With that thing FF could not be shipped for people for sure.
Does reducing usage of CPOWs will help get rid of the spinner, or it’s not connected?
@Chris:
CPOW usage from the content process could contribute. A CPOW representing an item in the parent process being accessed in the content process will block the content process while it gets the information in the parent. That could certainly cause the spinner.
I just tried out Nightly in a fresh profile. With just a handful of tabs open it was intolerable. I don’t know how anyone could use this for daily use in its current state.
I’m a fan. Not trying to be a Negative Nelly, just observing it seems to be a quite significant problem.
@Caspy7,
Your report is a useful datapoint, but something far far _far_ more useful from you would be a profile. Can you please send me one?
(If you’re on Windows, however, you’ll need to wait for bug 1161720 to be fixed before your profiles will be useful).
Mike, since I disabled all addons, and also updated Firefox nightly, the Big Tab Spinner seems to be gone.
As mentioned, I had AdBlockPlus, Greasemonkey and DOMI as relevant addons before. I’ve re-enabled ABP just now, and see whether the spinner re-appears.
However, I saw dom.ipc.processCount in the post above here (thanks, kwierso!), and upped it to 30, which will probably taint the testing results.
That’s a valid stance for uncommon addons. ABP is installed for 30% of our users, so you can for all practical purposes consider it part of the browser.
@BenB
I agree that serious performance problems resulting in tab spinners from AdBlock Plus is unacceptable, considering how popular the add-on is.
Manually enabled e10s on 40a2 . After restart with open tabs/windows saw the thobber. Set dom.ipc.processCount to 3. It might be placebo, but now it feels much faster and no throbber. Good.
@Ezh,
Yes, but by running with dom.ipc.processCount > 1, you’re robbing us of valuable performance data to help make each content process faster. 🙁
When you ask again, I can put the default anytime back.