Binary Chop Debugging and the Performance of CSS Pseudo Class Selectors in Firefox
We recently noticed something strange in the trunk of Amaxus. In Firefox, every click in the admin interface had a slight delay before anything happened. It was definitely a recent problem; it wasn’t in any of the release branches or any customer code, just in trunk. Chrome and Internet Explorer were unaffected.
Firebug’s profiler didn’t offer clues to the problem, and we couldn’t think of anything obvious that had changed that would cause this issue. So, to diagnose it, we used a technique called binary chop on our SVN repository.
Binary chop is a technique for searching a sorted list of values. In this technique, you split the difference between two known points then test and repeat until the issue in question is isolated. This takes (log2 N) comparisons, so if you were to guess a number between 1 and 1024, for example, I would be able to find it in a maximum of (log2 1024) or 10 guesses using this technique.
We were at revision r:6910, so we reverted to a known good revision, r:5000, and worked between them in a rough binary chop:
| Revision | Status | Diagnosis |
|---|---|---|
| 6910 | BUG | bug before 6910 |
| 5000 | OK | bug between 5000-6910 |
| 6000 | OK | bug between 6000-6910 |
| 6500 | OK | bug between 6500-6910 |
| 6750 | BUG | bug between 6500-6750 |
| 6625 | OK | bug between 6625-6750 |
| 6688 | BUG | bug between 6625-6688 |
| 6656 | BUG | bug between 6625-6656 |
| 6641 | OK | bug between 6641-6656 |
| 6649 | BUG | bug between 6641-6649 |
| 6645 | OK | bug between 6645-6649 |
| 6647 | OK | bug between 6647-6649 |
| 6648 | OK | bug introduced in 6649 |
This can be represented something like:

At this point, we checked to see what had changed. Most of it looked pretty standard, but one CSS rule was noticed:
*:active {
outline: 0;
}
We reverted this to its former state:
*:focus {
outline: 0;
}
Hey presto! Everything was running smoothly again!
So, why was this? We suspected it was caused by something called reflow, and that the “active” pseudo-class was causing the whole page to be re-rendered. Nicole Sullivan’s article goes into a lot of detail about reflows and repaints, which is well worth reading if you are having performance issues on your site. In this article, she confirms our suspicion that activation of CSS pseudo classes cause reflows. According to Opera, repaint is expensive because the browser must verify the visibility of all other nodes in the DOM tree, so it is unsurprising that it had such a marked effect.
We wouldn’t suggest that all debugging be done via binary chop, but sometimes it’s a useful technique for when an error has crept in and you haven’t got much to go on.