Adblock Plus and (a little) more

Creating quality software · 2008-09-13 15:56 by Wladimir Palant

It got quiet around Adblock Plus again after some great strides towards Adblock Plus 0.8. That doesn’t mean however that nothing is happening, on the contrary. However, when I was about to add another small user interface change (one of the few that are still due for 0.8 release), I noticed that this is way more complicated than it should be. Why?

You have to look at the history of Adblock Plus. Most of the original code was written on two days in December 2005. Goal was to create a cleaned up version of Adblock, and I was in a big hurry because I was afraid that Adblock project maintainer would soon loose interest again and go back to Adblock 0.6 (which was never released). There was not much time to do code design, but there also was no real need — that original code only had the features you would find in Adblock, and it was a very simple extension (even after it was released a little later with some additional features, it was only 25 kB as opposed to the 64 kB of the then-current Adblock version).

And where are we now? Yes, much has changed. My original code was never released as Adblock, instead I had to fork the project. The filters are no longer a plain list of strings stored in prefs.js where there are only two types of filters (simple filters and regular expressions). There are far more options now (whitelisting, comments, element hiding, filter options etc), there is also various metadata stored for each filter (enabled/disabled, hit count etc), filters are organized hierarchically (mostly due to filter subscriptions), and instead of bloating prefs.js with all that data we now have our own storage file with its own storage format. And rather than matching each URL against all filters, different filter types are applied in a different way and better (and more complicated) matching algorithms are used. The code size almost quadrupled. And still, the core Adblock Plus code remains almost as unstructured as it was at the very beginning.

You see the problem? We got to the point where changing anything in the core is very risky and requires many (sometimes non-obvious) considerations. And while so far regressions in Adblock Plus releases were very uncommon (largely thanks to the efforts of the development build users), this isn’t a good situation to be in. So after we have been largely rethinking Adblock Plus user interface for Adblock Plus 0.8 I decided to go a step further and redesign the core code as well.

The new code defines classes instead of using in-line objects for data. It makes use of inheritance to define properties similar to multiple classes. It divides responsibilities cleanly between components instead of requiring that each code part “knows” all the details. It has well-defined and documented interfaces that these components can use to communicate. And it has automated testing to make sure that bugs that happen in unlikely situations are still caught.

Of course, the increased use of object orientation comes at a cost. Memory use didn’t change but performance got somewhat worse again. But I think it is very well worth it, especially if you consider that it will be easier for people to contribute.

If you look at the source code repository, this code isn’t checked in yet. Reason is that while the core code already works well, some of the user interface still needs to be adapted (especially the Preferences dialog). Also, while there are now almost 500 automated tests, I still need tests for subscription downloads which have a large number of possible edge cases. But the work is progressing. And I will look into having JSDoc documentation of the core code published here and updated automatically.


Comment [5]

  1. steve · 2008-09-13 17:32 · #

    Wouldn’t storing the filter list in a SQlite-DB make your life easier? You would have easy access to all the filters. Updating/adding/deleting filters with SQL commands should be easy. You wouldn’t need to generate and parse the file yourself.

    Only problem could be the missing Firefox 2 support.

    Reply from Wladimir Palant:

    When this decision was made not even Firefox 2 was out. And most important decision criterion for me was performance – neither RDF nor JSON produced acceptable results. I am not sure whether even SQLite will perform better that a plain text file given that Adblock Plus will usually read out and write back the entire list (though this behavior can probably be changed if we have a database and no longer need to keep everything in memory). But since Firefox 2 will still be supported at least until December, that’s a theoretical consideration for now.

  2. Nils · 2008-09-13 21:26 · #

    mozStorage is supported in moz1.8/fx2

  3. ecjs · 2008-09-13 22:41 · #

    “The new code defines classes […] makes use of inheritance to define properties […] divides responsibilities cleanly between components […] has well-defined and documented interfaces […] has automated testing”

    That’s the way a Computer Scientist would think. Great !

    “Of course […] Memory use didn’t change but performance got somewhat worse again”

    I don’t understand. Why would it get worse ?

    Reply from Wladimir Palant:

    Because JavaScript is a scripted language. A method call is expensive, and when you use inheritance you call superclass methods a lot. The good news: it looks like current JavaScript performance work will solve that problem, and maybe in Firefox 3.1 the current code will be even faster than the old code.

  4. Anonymous · 2008-09-14 03:55 · #

    Would you consider making a release of Adblock Plus before your rewrite, so we can take advantage of the features you’ve already added without having to run a development build?

    Reply from Wladimir Palant:

    I want to complete user interface improvements – and for that I need to finish the rewrite. What would be the point of releasing something that is not done?

  5. Verb · 2008-09-14 08:29 · #

    “The increased use of object orientation comes at a cost. Memory use didn’t change but performance got somewhat worse again”

    Wladimir, I thought performance was your first and foremost priority. Has this changed? Why slowdown thousands of people’s browsers just to make it easy for few people to contribute? It’s not like you’re adding features everyday and surely people prefer simple extensions. (If you look at the FoxyProxy extension, you will see it has a huge amount of options and features, probably more than you’ll ever need.)

    Reply from Wladimir Palant:

    I’m not adding features every day – but when I do, I want to know that everything works before I release. There is currently only one filter list where the performance difference is noticeable. And even there, this will probably look very different already when Firefox 3.1 is released.

Commenting is closed for this article.