Adblock Plus and (a little) more

Impact of Adblock Plus on startup time - revisited · 2010-06-10 02:31 by Wladimir Palant

A few months ago Taras Glek blogged about extensions having a significant impact on browser’s startup time. One of the extensions he measured was Adblock Plus 1.1.3 and it didn’t make a good figure. Originally I thought that significantly optimizing Adblock Plus initialization wasn’t possible but I then found that using lazy evaluation for some values improved the performance of Adblock Plus 1.2 quite significantly. So I decided to check what things look like now.

Taras measured cold startup in his post which makes sense seeing his interest in file reading patterns. However, measuring cold startup times is much harder than measuring warm startup. Also, the difference between the two startup times usually isn’t something an extension developer can control (there isn’t much you can do once your extension is packaged properly). So I measured warm startup times using the method Vladimir Vukićević described in his blog. The table below sums up the results for a current Firefox nightly (build 20100609) on Windows 7. Each line represents 10 runs, two runs that took the most time were removed before calculating the average:

Clean profile 742ms
Adblock Plus 1.1.3 (no filters) 793ms
Adblock Plus 1.1.3 (EasyList) 2349ms
Adblock Plus 1.2 (no filters) 782ms
Adblock Plus 1.2 (EasyList) 1201ms
Adblock Plus 1.3a (no filters) 796ms
Adblock Plus 1.3a (EasyList) 1334ms
Adblock Plus 1.3a (en-US only, no filters) 803ms

One thing is clear: Adblock Plus 1.2 was indeed a huge improvement reducing the time to process filters to almost one-forth of the old value. All the other overhead of the Adblock Plus initialization is still pretty small in comparison (40ms to 400 ms). It also seems that the number of locales included doesn’t have an effect on the warm startup time — a regular Adblock Plus 1.3a build (43 locales included) and an en-US-only build didn’t perform significantly different (7ms difference isn’t meaningful on my laptop despite all the averaging). The locales might still influence cold startup time but I somehow doubt that.

It is somewhat disturbing that the filter processing time went up again for Adblock Plus 1.3a (which wasn’t a regular development build by the way, those are somewhat slower due to time measurement code — I had to create a release build to get comparable times). This change didn’t show up in any of the performance tests that measure various aspects of the initialization and I am not aware of any changes that might have caused this, will need to find the regression window. Other than that I expected the initialization of Adblock Plus 1.3a to be somewhat faster due to much more code being loaded from startup cache, however the impact of this change is apparently too small to show up here.


Comment [5]

  1. Johnathan Nightingale · 2010-06-10 06:05 · #

    Way to go bringing the startup impact down, Wladimir! Now let’s see if we can get it the rest of the way. :)

    I was thinking about this, a couple things came to mind:

    1) It looks like adblock is doing all its init right in the critical load path – That’s bad news because it means no yielding to the event loop. Is it possible for you to do what Firefox itself does (and most addons do) and at least wrap your startup stuff in a setTimeout, so that it’s not in the hot path? Far from being a meaningless deferral, this means that we can get the browser up to “alive and responsive” sooner – and then you can have your startup time. :)

    2) If rules loading is the big cost, and it certainly seems to be, have you considered a Bloom filter as a lightweight system you could use – perhaps only at startup while you wait for your rules to load behind the scenes?

    3) Speaking of behind the scenes, what about doing the rules loading in a chrome worker thread, so that UI isn’t blocked?

    Just some ideas – AdBlock is a big part of many people’s Firefox experience – I know the Firefox team would love to see it as performant as possible.

    Reply from Wladimir Palant:

    I was surprised myself – the performance tests did show some improvement of course but there was no indication that the overall impact would be that huge. I guess that there are some hidden delays that I usually don’t get to measure (garbage collection?).

    1) Actually, you are looking at the wrong file. Adblock Plus usually initializes during profile-after-change handling, in version 1.2 the file responsible is AdblockPlus.js. We do delayed initialization in Fennec however where it is essential. The reason why this isn’t done in other browsers – we would enter a racing condition with session restore, restored web pages might load before Adblock Plus filters are initialized, with all the ads still in place. While I hate delaying Firefox startup, this kind of inconsistent behavior would IMO be worse and cause quite some user frustration. Which is why the approach so far has been to do as little initialization as possible during startup and initializing everything else later as needed.

    2) Interesting algorithm, thank you for the pointer. Unfortunately, I doubt that it will perform well in JavaScript (costs of calculating the hash of a string will be prohibitive). This is similar to how Rabin–Karp algorithm is theoretically superior to the matching algorithm used by Adblock Plus but turned out too slow when implemented in JavaScript. But I have my own lightweight structure for determining when something might match a filter, I could load only that data and do the full initialization when we get such a potential hit. The problem with this approach: it won’t help with all the filters, most notably not with element hiding filters. But it is still worth considering.

    3) I don’t think that worker threads will do here – the initialization produces lots of data structures, passing them back to the main thread through JSON will only create unnecessary overhead.

  2. foo · 2010-06-10 16:36 · #

    “measuring cold startup times is much harder than measuring warm startup”

    Well, it seems you primarily test on Windows, but in case you also test on Linux, it’s actually pretty easy, because you can purge the cache in a single command (as root):

    # echo 3 > /proc/sys/vm/drop_caches

    Maybe there’s something similar on Windows?

    Reply from Wladimir Palant:

    Yes, I am aware of that. However, I don’t have a physical Linux machine right now and I don’t want to start measuring in a VM. Unfortunately, there is nothing comparable for Windows – as several Mozilla people found out the hard way. The best solution they could come up with was running everything from a (virtual?) USB drive and disconnect the drive between the runs.

  3. christian louboutin · 2010-07-10 06:23 · #

    Like your article, it gives me a lot of help,hope you like what.

  4. z · 2010-07-15 12:08 · #

    Under windows you could try cacheset

    Reply from Wladimir Palant:

    See – this has been considered.

  5. armani sunglasses · 2010-07-16 06:56 · #

    Thanks for such a great post and the review, I am totally impressed! Keep stuff like this coming.

Commenting is closed for this article.