We quietly shipped Firefox 11 with a bunch of performance fixes that both reduce the amount of memory that Firefox uses, and improve the responsiveness of it’s user interface.
These types of changes are not easy to talk about. Often they’re very technical, and meaningless to anyone but the developers involved, which is probably why we usually don’t enumerate them in the the release notes or other public announcements. “Firefox is 74% faster when you open menu X, and twice as fast in some garbage collection scenarios!” Yeah, not an eye-popping headline. We could do a lot better in communicating these improvements in broadly meaningful ways though – nice graphs or some competitive site like arewefastyet would help a lot. But until then, here’s a short summary of the improvements in Firefox 11. And if you know of other performance fixes that don’t fall into the categories below, please add them in the comments!
Memory Use (aka “memshrink”)
The Memshrink project has been going for quite a while now, led by Nicholas Nethercote. He blogs weekly updates on the project’s activity. According to Bugzilla, there were 29 memshrink bugs marked fixed during the Firefox 11 development cycle – four of which were P1, or very high priority. Some of the fixes were related to tools and detection methods, but many are actual reductions in memory use. The changes that made it into Firefox 11 include fixes for detected leaks, removing of zombie compartments, lazy-loading data, reducing the size of some caches, reducing memory used while scrolling, and many more.
UI Responsiveness (aka “snappy”)
The Snappy project started last December, and is run by Taras Glek. Its aim is to improve the responsiveness of the Firefox UI. Taras has been posting weekly updates on Snappy activity on his blog. Bugzilla shows 15 snappy bugs marked fixed during the Firefox 11 development cycle. The project had just started, but there are still some significant wins in this release! Firefox 11 includes reductions in queries in the bookmarks system, reduced preference lookups, faster data collection for session restore, and various improvements in the DOM code.
While it’s not related to performance, I do want to call attention to something that many people don’t seem to know: In Firefox 10 (yes, the previous release) we stopped marking most add-ons incompatible when you upgrade. That means that a LOT more of your add-ons will continue to work when you upgrade Firefox from here on out. The only add-ons that still require compatibility bumps are those that have binary components, since they need to be recompiled against the current version.
The Performance team and some of the Firefox team are spending the week in Brussels, laying waste to some of the performance issues in the browser.
I’ll be uploading pics to flickr with the tag ‘perfworkweek2012′.
I remixed about:memory using D3 to make a treemap visualization of how loaded URLs are using memory in Firefox.
Load it by clicking the widget on the add-on bar, or Cmd/Ctrl+Shift+Y
This visualization focuses on which web pages are using large amounts of memory – this is not a complete accounting of all memory being used. This doesn’t yet show how much is being used by some of the Firefox internals.
Add-on installation does not require a restart. Only tested on Nightly builds.
Dormancy ‘retires’ tabs that have gone unused for a while, freeing up that memory. It then restores the tabs to life when accessed.
While Firefox 9 adds restore-on-demand for users that restore their session by default, many users will never benefit from it. This add-on targets users who don’t restore session, but do have long-running instances of Firefox and many tabs. This might land as a core feature in Firefox 9 (https://bugzilla.mozilla.org/show_bug.cgi?id=675539).
NOTE: This is highly experimental, has only been tested on the Nightly builds, and probably will destroy your session. You’ve been warned.
Tabs are considered inactive when they haven’t been selected in longer than 5 minutes. To change that, set this pref to a value in milliseconds:
Tabs are checked for inactivity every 5 minutes. To change this, set this pref to a value in milliseconds:
- Awesomebar entry for dormant tabs shows data URI
- Sometimes dormant tabs have no title and no favicon
EXPERIMENTAL. MAY EAT YOUR SESSION OR DO OTHER BAD THINGS.
I wrote an add-on for Firefox 4 that tracks how long various parts of the browser’s user-interface take to load. It does not require a restart of the browser.
- It measures the duration between ‘popupshowing’ and ‘popupshown’ events. This covers menus, menu-like things, and those floating panels you’re starting to see everywhere.
- You can see your results at about:response. There won’t be anything there if you just installed the add-on. Browse around for a few days and then check it out.
- It doesn’t track popups without an id yet. It could also be nicer by showing the containing menu name if available.
- I’d like to add window load times. What else in the front-end could we be measuring? I was thinking about <command> execution, but there’s not a way to do that without modifying the core, afaict.
- Perhaps we could add a button for users to submit their anonymized data somewhere.
Try it out, let me know if you have any problems. The source code is available on Github.
I’ve been focusing more on Jetpack development this quarter, but will still be posting performance round-ups regularly here. In fact, here’s one now:
- Taras Glek continues to blog his progress on improving the binaries we ship, talking about how reordering binaries improves memory use as well as load time, leveraging GCC’s PGO for fast startup, and finally about Icegrind, his Valgrind plugin that generates a log of the order of access to mmap’d files.
- I finished and checked-in my changes to the Tinderbox Pushlog, adding a new feature that provides at-a-glance comparison in performance test results between any two pushes on the page (screenshot). It will go live next time Marcus pushes changes out to his server. But he’s not online at the moment, so I don’t know when this feature will go live. Heh, it went live moments after I published this post.
- Heather Arthur and Clint Talbert are working on a project to add performance data to Addons.mozilla.org for extensions. They’re starting with the effect of a given extension on Firefox startup time. Follow along on the bug, or watch project Dirty Harry on Github.
- Improving the AMO extension validator: AMO scans uploaded extensions and reports problems to the authors. For performance best-practices, we should at least warn the authors if possible if their add-on is doing something that’ll make Firefox slow. This bug is for warning about add-ons that don’t have their content in a JAR file. If you see any thing in the best practices guide that can be statically detected, please file a bug for it here.
If you have any other performance-related bugs, blog posts, anecdotes or other tomfoolery, post it in the comments!
As I mentioned in my previous update, the scope of these updates has expanded beyond start-up time. That said, I can’t keep track of everything! So if you have an update, email it to me if you want it in the post, or just add it in the comments.
- First, I just have to say that Marco’s fix for bug 542943 has changed the way I think about browser restarts, removing the fear entirely. It turns out that, for me anyway, the majority of the slowness involved in restarting was waiting for the process to exit. After Marco’s landing, it’s nearly instantaneous.
- While I was away, Taras blogged nearly daily about his findings while working on Linux code locality. He first posted a graph of I/O from library loading, then a long post about why library loading sucks on Linux, followed by some findings regarding madvise and prelink, finally posting about linker inefficiencies and SuSE’s workaround.
- Mike Wu and others are moving forward on the “omnijar” project, which moves most of the core application files into a single JAR file. Taras described it as “extreme filesystem makeover”, and found ~10% start-up improvement with this approach on the desktop.
- Clint Talbert and Heather Arthur are beginning work on a project that measures add-on performance, that will hook into AMO to show developers how their add-ons perform.
- Drew Willcoxon got r+ on bug 536893 to allow asynchronous opening of Places query results. Once we start using the feature, expect bookmark and history UI to get snappier!
- Taras got review on bug 516085, which consolidates access to core services that currently accessed hundreds of thousands of times during a browsing session.
- A bunch of people have added tips to the add-on performance “best practices” document. I’ll be cleaning it up and moving it to MDC soon.
- While the tinderbox pushlog is fantastic for viewing per-checkin results, and a broader view of tree activity, it doesn’t provide any facility for comparing the results of performance tests between landings. So I spent some time this week writing an addition that allows you to select any two pushes, and view a comparison table showing the difference in performance across all tests on all operating systems for those revisions. I’ll clean it up, and try to get it deployed, but regardless will make it available as a Jetpack or Greasemonkey script sometime next week.
For more info:
- Startup performance activity is tracked here.
- Add-on performance efforts are being tracked on this page.
- Weekly performance results for all measurements are available on the snapshot, and trends available on the dashboard.
A couple of notices: First, I’m going to start including various performance-related items in these posts that aren’t purely about startup time. There’s a whole bunch of activity happening that isn’t really rolled up anywhere, so it might as well be here. Second, I’ll be out on vacation in Florida next week, so there will not be a status update.
- Last week I forgot to add that Marco Bonardo landed bug 542943, which removed a hash of all bookmarks that stayed resident for the lifetime of the application. This resulted in a 97% improvement in shutdown time for our test of a very large bookmarks+history collection.
- Ted’s taken over the static build project, and has new patches up.
- Taras is working on Linux code locality via a Valgrind plugin he’s writing, with help from those folks.
- At the platform work week Taras talked to Ehsan, who it turns out had a bunch of ideas for improving startup there. I’ve filed bugs from Ehsan’s notes for better Windows code locality, binding DLL function addresses to the executable, DLL rebasing, and DLL lazy-loading.
- The add-on performance “best practices” document is getting bigger and better. If you have ideas for improving add-on performance, please add them to the doc!
- All of our add-on performance efforts are being tracked centrally on this page. If you want to get involved, hop on one of those bugs. If you want to stay updated, “watch” that page and you’ll get emails whenever it’s updated.
- I’ve updated the main Performance wiki page. The top sections are now up to date. Next I’ll be updating the testing and reference sections, and breaking out the task-specific content and moving it to an updated table of performance activities, like we currently have for startup, addons, etc. When the page is more manageable, I’ll remove the TOC that’s pushing everything below the fold.
- As usual, the table of active startup performance activity is here.
No update on the ongoing code projects this week. However, we investigated the extension performance work I mentioned last week, and got a conversation going, with posts by Taras, Asa and myself. I’ve listed the various ideas and approaches that came out of those posts and comments here.
Extensibility is a double-edged sword. It’s a keystone feature in Firefox – differentiating even now that just about every other browser has some vector for augmentation. However, along with the freedom and power of Firefox extensions comes the ability to slow the browser down. And worse, users and developers have little or no visibility into the causes of poor extension performance.
Not all extensions slow Firefox down. But they can. To prevent that, we need to do three things:
- Make it *easy* for extension developers to keep their extensions fast.
- Allow users to see the performance effect of their extensions.
- Mitigate the effects of badly-behaving extensions in Firefox itself.
For Extension Developers
First, we need to loudly and clearly educate extension developers, and provide them tools. Some ideas:
- Write an extension performance “best practices” guide on MDC.
- Build warnings into Firefox, that highlight code that might perform poorly (bug 550242).
- Provide a try-server that allows extensions to be uploaded and installed into the test profile.
- Perform automated performance testing of extensions upload to AMO (bug 458990, maybe?)
- Ensure that Jetpack generates extensions that are models for good behavior.
Users should be able to make informed choices about the extensions they install, and be able to monitor the effect of extensions on their browsing sessions. We could:
- Provide performance information for extensions on their pages on AMO.
- Build a performance dashboard similar to about:memory, but tracking startup time, page-load time, and browser UI behavior such as menu responsiveness. Given a visualization of these things over time, users can see the effects of installing different extensions.
In the Core
There are also things we can do to mitigate poor performance in core Firefox code. This is being discussed in bug 533038.
We’re already working on some of the ideas listed above. Ping me in #startup on irc.mozilla.org if you want to help out. If you have ideas for other ways to improve extension performance, or to communicate back to users and developers, let me know in the comments.