Adblock Plus and (a little) more
Why you should make your next add-on restartless · 2012-07-12 14:18 by Wladimir Palant
Note: This article is not about extensions based on the Add-on SDK (Jetpack). You don’t have to use the SDK to create a restartless extension. Just wanted to point this out explicitly to avoid confusion.
An extension that will install without requiring a Firefox restart? This was a nightmare to develop not too long ago. Fortunately, things changed and the last showstopper bug was fixed in Firefox 8. Effort to create a restartless (or bootstrapped as it is called officially) extension is acceptable now. In fact, I have converted all my extensions and removed support for classic non-restartless extensions from my build tools — I am certain that I am not going back.
So, how did it go? It was a mixed experience actually. The new extension type has significant advantages:
- The user experience is simply better. It is nice to install an extension within a second and to continue doing whatever you’ve been doing before — no restarting the browser, no session restore. And it also helps a lot if the user experiences issues: disable the extension, check whether the issue is gone. Takes only a few seconds.
- Testing a restartless extension during development is easier. Do you still use complicated test environments so that you can test changes without restarting the browser? Do you keep in mind which parts of your extension can be updated this way and which ones still require a browser restart? I simply use Extension Auto-Installer to update the extension in the browser instead — it’s fast and I actually test the same build that my users will get later.
- A simple extension is simple. Classic extensions require you to create numerous files and a directory structure. A restartless extension doesn’t need more than the install manifest (
install.rdf
) and a single JavaScript file (bootstrap.js
) in the same directory. - You have a centralized and logical place to run your code. The
bootstrap.js
file gives you a single environment that will be around for as long as your extension is enabled. Compare that to classic extensions where most extensions use overlays as a trick to inject scripts into the browser window. And then they struggle attempting to synchronize the code instances in different windows, e.g. by abusing preferences for something that doesn’t need to be persistent. - You actually own the environment where
bootstrap.js
code runs. You don’t have to worry that another extension will declare a variable with the same name — you are not in a shared environment, only your own code executes here. - If your extension leaks memory or doesn’t clean up after itself properly you will notice — because even after disabling the extension and minimizing memory use
about:memory?verbose
will still display a compartment belonging to your extension (thanks to Chris Finke for reminding me, I originally forgot listing this point). Investigating the memory leak will still be tedious but at least you will know it is there.
There are disadvantages as well however:
- Converting an existing extension can be rather complicated, especially when it comes to user interface integration. In particular, making Adblock Plus restartless turned out way more time-consuming than I expected. This is of course easier if an extension is restartless from the very start.
- The platform mechanisms used for restartless extensions aren’t quite as well-tested as for the classic extensions. I didn’t notice it when I published my first eight restartless extensions, but Adblock Plus with its millions of users is a bug magnet of course. So I very soon discovered bug 770669, rediscovered bug 744833, and there seems to be yet another similar issue that I didn’t manage to reproduce yet.
- Many tools and helpers that the Gecko platform provides you with weren’t built with extensions in mind that can come and go at any time. So in many cases you will have to take a more complicated route and do things manually that should normally be handled by the platform.
- You cannot use XBL. And you have to append a random parameter to the URL when loading string bundles. Such annoyances will hopefully get less as the platform is improved.
- The documentation is unfortunately not very helpful. MDN has lots of examples and tutorials but those tend to ignore features that are less than five years old. You will get several detailed tutorials on creating classic extensions or using overlays but not a single one will mention even the existence of restartless extensions or the Add-on SDK. You have great code snippets for common tasks but these never use new and highly recommendable helpers like Services, FileUtils or NetUtil. Even the XPCOM examples were occasionally ignoring XPCOMUtils or using an approach that stopped working when Firefox 4 came out (I think that I got the important ones fixed however).
For me, the advantages clearly outweigh the disadvantages. If you already have a classic extension then you may wait with converting it until you actually have time for that. But if you are planning a new extension then you certainly should make it restartless. I consider the complete lack of documentation the biggest problem right now — MDN needs to shift its focus from classic extensions to restartless extensions. I want to publish a few articles on how I solved the typical problems, this will hopefully be a good start.
Comment [3]
Commenting is closed for this article.
Chris Finke · 2012-07-12 15:51 · #
How do you go about debugging memory issues in restartless extensions? Occasionally, I’ll have zombie compartments left (according to about:memory?verbose) after uninstalling, and while I know in general what to look for in the code, it’s trial and error at best.
Reply from Wladimir Palant:
That’s one advantage I forgot to mention – you actually notice it when you leak memory because compartments belonging to your extension stay around after you disable it. Debugging memory leaks is always a bit tedious but with about:ccdump (https://addons.mozilla.org/addon/cycle-collector-analyzer/) it is quite doable. You get the CC data, look through the sandboxes in the list, identify the one belonging to your extension (the compartment that leaked) and display the roots for it. Then you have to understand why that root is connected to your extension (current version of about:ccdump doesn’t make that step easy enough, I am saving the log and processing it with my own script).
Manuel Reimer · 2012-07-12 18:01 · #
I followed all your blog posts about “restartless extensions” and for me it definitively seems to be a bad idea to do this.
Many things have to be done in own code, that would be handled by the backend code, otherwise, like overlay loading, component registration and many more.
In my opinion, Mozilla addon development already has a very steep learning curve, but with restartless, it gets even steeper.
I’ll keep my addon (PrefBar) the way it is until the whole process of porting to “restartless” gets simplified a lot. In my opinion, the whole restartless thing is primarily optimized to be used with “Jetpack” and not to be used by the average addon developer.
Reply from Wladimir Palant:
Yes, at the moment some things require more work than necessary and aren’t good enough for newbies. But we are mostly talking about relatively simple code that is easily generalized. I do hope of course that this code becomes part of the platform in future (e.g. component registration for restartless extensions can be easily made part of XPCOMUtils).
Tobu · 2012-07-15 15:49 · #
s/even after disabling/because after disabling
I didn’t understand it right the first time, I took it to mean that showing compartments after disabling was done on purpose rather than a symptom and only got it after seeing your next post.
Reply from Wladimir Palant:
I’ve slightly adjusted that passage, hopefully it is easier to understand now.