Open Opened 12 years ago Updated 5 months ago

# Recent Beta and Aurora exhibit constant CPU load while idling displaying about:home

6 Branch
x86_64
Windows 7
Not set

UNCONFIRMED

## Attachments

### (5 files)

 928.81 KB, text/plain Details 7.00 KB, text/plain Details 125.32 KB, text/plain Details 479.52 KB, application/octet-stream Details 3.09 KB, patch Details | Diff | Splinter Review
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0
Build ID: 20110811165603

Steps to reproduce:

I'm running multiple channel builds of Firefox on a test machine to see when the memory usage will improve enough that I can upgrade Firefox 3.6 on aging laptops. The test machine is headless, Firefox is always started in a remote desktop session.

I'm checking idle memory usage by opening Firefox and leaving it idle on the default about:home page. Each channel build runs with a separate and basically empty profile by running:

<specific\path\to>firefox.exe -no-remote -P <channelName>

The test profiles have only Addblock plus add-on and Flash plugin installed, but I can reproduce the behavior with a completely fresh profile, without any add-on. The about:home page is not displaying any demanding content, it happens even with the newsletter signup snippet.

Actual results:

In the last few days I've observed that the CPU load on the Beta and Aurora channel doesn't drop after startup, it stays at around 5% CPU load no matter how long I leave the Firefox running. The same thing happens even with a completely fresh profile. The test machine is fairly beefy (Xeon W3565 with 12GB of RAM and a SSD for %ProgramFiles% and %LocalAppData%) so it should not be the cause of the problem.

Expected results:

The CPU load should drop to basically 0% after Firefox startup. The current behavior would be especially problematic on laptops.

Please let me know if you need any further information.
Keywords: perf
Hm, it looks like this was an issue with the about:home page itself, I could not reproduce the increased load yesterday or today, did the about:home snippet change lately?

I did manage to reproduce it on Sunday on my 32bit Vista laptop, so it wasn't specific to the test machine. The problem was much more noticeable if I started multiple -no-remote Firefox processes, each with its own fresh profile (e.g. the processor load of each Firefox process was around 5% with 3 concurrent processes running and around 10% with 10 concurrent -no-remote processes running).
I experienced this issue running the Firefox 7 beta on a quad-core Mac Pro with Snow Leopard. CPU usage hovers between 75% and 90% when I have an about:home tab active. The CPU usage drops down to about 2% when I switch to a different tab.
Ryan -> Do you have multiple instances running like Ziga was? Can you reproduce the issue with Firefox running in safe mode?
Can someone who is seeing the problem on OS X install a shark build (e.g. ftp://ftp.mozilla.org/pub/firefox/nightly/latest-mozilla-aurora/firefox-8.0a2.en-US.mac-shark.dmg ) and then, when displaying about:home, do a Sample Process in Activity Monitor? You can then paste the result of that here (or put it in a text file and then attach that here).
Product: Firefox → Core
QA Contact: general → general
I've attached the process sample output, generated from the linked Shark build launched with the -safe-mode flag on OS X.
That sample shows that some time is spent running a setTimeout and a bunch more is spent running script and drawing to a canvas from what looks like a requestAnimationFrame callback.

But as far as I can tell, neither one of those is used by about:home by default, unless snippets can inject script?
I know recently Runfield demo has been pushed to some users as an experiment, in a snippet.
Product: Core → Firefox
QA Contact: general → general
Whiteboard: [about-home]
I don't know if it helps, but I observed the originally described problem again over the last weekend. I made sure that Runfield was not the snippet that was displayed on about:home, because it looked like it could be resource heavy. I managed to reproduce the problem without any addons, the easiest way to see it was if I ran multiple -no-remote processes, each with its own fresh profile. I caught a few stack traces of the main thread with Process Explorer when the CPU usage was high, maybe they'll be of some help.
Every single one of those stack traces is under canvas drawImage called from JS, with the JS called from the refresh driver directly.  The only JS the refresh driver should be calling directly is requestAnimationFrame callbacks.
This is a performance sample taken from a nightly shark build just after opening to about:home. Indeed, runescape was recently pushed but it was not shown this time, instead i see a link to webifyme. Several add-ons are installed, but I get the same result with them disabled.

Hope this helps.
I saw this issue again yesterday and dug a bit deeper. I noticed this in chrome://browser/content/aboutHome.js::showSnippets():

// Scripts injected by innerHTML are inactive, so we have to relocate them
// through DOM manipulation to activate their contents.
Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) {
let relocatedScript = document.createElement("script");
relocatedScript.type = "text/javascript;version=1.8";
relocatedScript.text = elt.text;
elt.parentNode.replaceChild(relocatedScript, elt);
});

IIUC, it does this to run the following script included in the snippets page:

<script type="text/javascript">
var snippet_container = document.getElementById('snippetContainer');
var snippets = snippet_container.getElementsByClassName('snippet');
if (snippets.length > 0) {
var show_snippet = snippets[Math.floor(Math.random()*snippets.length)];
show_snippet.style.display = 'block';
activateSnippetsButtonClick(show_snippet);
} else {
localStorage['snippets'] = '';
showSnippets();
}
</script>

Unfortunately, showSnippets() consequently also loads the Runfield demo, even if some other snippet is chosen to be shown at the end. So the observed high CPU usage is probably caused by the Runfield demo, sometimes running in the background.

Maybe a better solution for aboutHome.js::showSnippets() would be to randomly select and load a signle snippet by itself, without the help of the script in the snippets page.

Some other observations:

- The Runfield snippet as currently served is broken, one of the script tags
is missing a javascript // comment token in front of the the cdata ]]> CDEnd
token. I don't understand why it works sometimes in the about:home page, if I
inject the unmodified snippets page into a normal page served over http I get
syntax errors. I think this is the reason why I couldn't always reproduce
this bug.

- Should the SNIPPETS_UPDATE_INTERVAL_MS constant be changed into a about:config
preference? The "browser.aboutHomeSnippets.updateUrl" preference was useless
for experimenting with that interval being hardcoded.

- The Runfield snippet is being served to Beta audience, I don't know if that
is intentonal. (The snippet text says "Play Runfield and experience the
latest HTML5 innovations in Aurora."). Note that mozRequestAnimationFrame
doesn't seem to be throttled in minimized windows on current Beta (7.0),
while it is throttled in Aurora.

- The Runfield snippet causes high CPU load when it is loaded in the
foreground tab, which is somewhat expected. If I then switch to a
different tab (or minimize the browser window on Aurora), the CPU usage
drops, which is commendable. However, if I switch to a different maximized
window, even on Aurora, the CPU usage remains high. I guess this could be bug
646937. Could the mozRequestAnimationFrame also be throttled when the window
receives WM_SHOWWINDOW message with SW_OTHERZOOM lParam?

- The Personas snippet loads an iframe over http protocol into what is
otherwise a secure https page.

The aboutHome.html file in the attached zip folder contains a standalone
version of about:home with a fixed snippets page (Runfield syntax error). It
reliably reproduces the problem described in this bug for me.

The aboutHomeModified.html file contains a modified showSnippets() function
which loads a single snippet, consequently the CPU usage stays low unless
the Runfield snippet is chosen to be shown on about:home.
Attached patch untested patchSplinter Review
Here is a possible patch for this issue, it worked in my limited testing with standalone about:home. Note that I haven't actually built it or ran the added tests, I don't know how to do that yet. I'm also unsure if I used the createContextualFragment correctly, the draft specification is not entirely clear how it is supposed to work, but it seems to work in practice and it looks better than the previous script movement hack.
Ziga, if you think your patch is ready, you should ask for a review.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.