Wednesday 24 June 2009
Whitespace Begone
I just landed on trunk a small improvement to page-load performance. Typical HTML documents contain a lot of markup like
<body>
<div>
<b>Hello World</b>
</div>
</body>
In the DOM, there are four text nodes which contain only whitespace. Up until now, in Gecko we created one "text frame" to render each text node. However, this is a waste, since whitespace-only text nodes before or after a block boundary don't affect the rendering; they are collapsed away (unless CSS white-space:pre
or certain other unusual conditions apply).
So I did some measurements of our page-load-performance test suite (basically, versions of the front pages of popular Web sites) with an instrumented Gecko build to see how much could be saved if we avoid creating frames for those whitespace DOM nodes. It turns out that in those pages, 65% of all whitespace-only text frames were adjacent to a block boundary (i.e., the first child of a block, the last child of a block, or the next or previous sibling is not inline) and don't need a frame. That's 30% of all text frames, and 11% of all layout frames!
Actually suppressing the frames was pretty easy to implement --- it helped that Boris Zbarsky has recently done some magnificent hacking to make nsCSSFrameConstructor more sane. Handling dynamic changes correctly was a little tricky and actually took most of the development time. Our test suite, which is pretty huge now, caught some subtle bugs. But the patch is on trunk and seems to be a 1-2% improvement in average page load time. It's also a small reduction in memory usage. It also makes dumps of the layout frame tree much easier to read because a lot of pointless frames are gone.
What's probably more important than all that is that this makes it easier to separate our implementation of blocks into "blocks that contain only blocks" and "blocks (possibly anonymous) that contain only inlines" without regressing performance, because we won't have to create anonymous blocks just to contain irrelevant whitespace.
Comments
Thanks
http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/
Are you seeing something different? If so, with what setup? I'm on OS X 10.5 here; the results might theoretically be different on other OS X versions or on Windows.
This is huge, it contains lots of tables and not really a day-to-day example, but still I find that embarrassing: http://secfilings.nasdaq.com/edgar_conv_html/2004/03/08/0001047469-04-006934.html
Or what about DOM performance? FF (just tested current trunk nightly) gets stomped by Safari 4 in nearly every of Dromaeos DOM tests (e.g. DOM Modification 84 runs/s vs. 230 runs/s).
So I agree that each percent speed improvement is nice and precious. But the rub must be somewhere else.
As far as Dromaeo goes, there are some known issues where it's not really measuring the DOM performance in some cases (e.g. measuring JS interpreter overhead because the harness is designed in a way that Tracemonkey doesn't trace currently), as well as some known issues where Safari 4 defers some work on DOM modifications that we do eagerly (so if you make the same modification a bunch of times in a row the time they need doesn't scale linearly with the number of times you do it). We're looking into doing some of the same things; they'll help benchmark numbers a lot and actual applications and web pages a lot less...
And to be clear, I really do appreciate the examples; I _did_ ask for them, after all. We're definitely slower than Safari in various cases, and we need to fix those. It's just that we know what a lot of them are, and in most of the rest the comparison is being done in a ... hamhanded way. See http://weblogs.mozillazine.org/bz/archives/020099.html for a typical example.
And I see that synthetic benchmarks are always to be read carefully and need some background knowledge.
I'm not interested in "here and here FF is 10% behind, so it's a bad browser". Though with such "tests" I as a user end up with when trying to pinpoint a bottleneck. All tests I'm running not for themselves but to find out what makes FF just feel slower in real everyday usage.
Thanks for pointing me to this page; I'll look into how we can make this faster.
Bug 501848 in particular can easily be biting other pages, and I'm glad you brought it to my attention!
But thank you for looking into it, Boris.