Mozilla is fighting poor performance in Firefox on many fronts. Firefox 3.6 was already a significant improvement over 3.5, and Firefox 4 promises to be lightning fast.
However, Firefox is already pretty fast. Seriously. If you download and install Firefox and run it on a clean profile, it should open quickly and be very responsive. Having a large history and bookmarks database can slow things down a bit, but I think we all know why many of us wait multiple seconds for Firefox to open: add-ons. Specially extensions.
Performance hasn’t really been a big concern for add-on authors. I know that when I test my add-on in my test profile, the slowdown is almost imperceptible. But once you have 5 or 6 add-ons installed, you realize how their combined weight can be very detrimental to user experience. We should care about add-on performance, and very soon we’ll have to.
Dietrich began the add-on performance conversation with his post Firefox, Extensions and Performance, and now with the help of Heather Arthur, we have a modified Talos system measuring the startup performance for the most popular extensions. We think this system should eventually be integrated into AMO, so that we can have a performance dashboard that allows authors to compare their own add-on performance to a global average, or maybe a series of standards we set. But for the moment we’ll be doing things by hand.
I spent some time last week contacting the authors of the add-ons with the most impact on startup times, and the response has been very positive so far. Since I didn’t want to just tell authors to “see what you can do”, I spent some time analyzing their code to identify the most probable reasons for the slowdowns. After a while some patterns began emerging, and I realized that improving startup performance for extensions is not very hard, and can be summed up as a couple of simple guidelines.
I also realized that I was just as guilty with my add-on, and that I needed to work on improving its startup performance. I spent the weekend working on it, and the results were very surprising.
Case Study: Fire.fm
Fire.fm is not the most complex of add-ons, but it does have a wide variety of features and some very complex flows and logic. I knew that there were several areas for improvement, but I was skeptical about the real impact those improvements would have. I thought I could shave off a few milliseconds, but not much more.
First, I needed a testing environment. Measuring Startup provides a very easy method. I tested on Mac OS X 10.6.3, and my testing produced these figures:
Firefox 3.6.4, clean profile: 703.1 ms
Firefox 3.6.4, with Fire.fm 1.4.4: 919.2 ms
So, the latest version of my add-on added more than 210 ms to startup time, an increase of about 30%. Needless to say, I wasn’t happy. 5 add-ons like Fire.fm in a user’s profile would probably increase startup time more than one second! It was unacceptable.
I had several ideas on what I should fix, and the one that I though would help the most involved changing the startup flow significantly, so I left that one for last. I began with the easy ones, which basically consisted on loading a number of modules and variables only until they were needed.
When I was done with that, I decided to take a break before tackling the more difficult tasks, and I decided to test again. Startup time was down to 800 ms! I didn’t expect that at all. Making the simplest of changes had produced a very clear difference, and I still wasn’t done. So, with this new motivation, I spent some time rethinking the startup flow (quite a headache for this particular add-on), and after making it work I ended up with this:
Firefox 3.6.4, with Fire.fm 1.4.5 (dev): 760 ms
The new build was adding only 57 ms to startup time, about 8% of overhead.
Wow. And I’m not even done. There are still some fine-tuning to do that will probably reduce that number a little more. I hope to release 1.4.5 very soon now that I see the significant difference that it will make to thousands of users. This is something I should have done long ago.
OK, so now let’s get to the real meat of this post: what can extension developers do to improve startup performance in their add-ons? Here are my recommendations:
- Do not load or run code before it’s needed. Add-ons can have extra features that are only available depending on user preferences, and others have most of their features depend on a user being logged in to a service. Don’t load at startup something you won’t need at the time. This leads to guideline #2:
- Do as little as possible in your load handler. Most add-ons have a load event listener in the main overlay that runs their startup functions. Ask yourself: is there anything I can’t run 100 ms or even 500 ms later? If there is, just use an nsITimer or the setTimeout function to delay running this code . The Firefox window will be able to load sooner and your startup code will run almost instantaneously afterward, in parallel with the loading of the homepage or the saved tab session. The browser will now load faster, and your code will still load at startup for all practical purposes.
I think most non-trivial add-ons can greatly improve their startup times by following these simple guidelines. All add-on authors should take the time to review them and see if there’s anything else they can do to help Firefox load with as little overhead as possible. Add-on performance is increasingly important for us, and it will probably become part of our code quality requirements in the near future. Act now, and help us make Firefox 4 the greatest browser ever!