7 ms·
A Shocking Truth About CSS
- ihumanable 17y agoJohn Resig (of jQuery fame) talks about why this approach was taken in the design of the sizzle engine that powers jQuery. Its towards the end of this talk (which is quite good by the way), I would find the exact time but my work internet thinks its inappropriate content and won't let me watch the video :(
- todd3834 17y agocould you post a link to it?
- goodside 17y agoScroll to the botom, and: 11:44:33 AM Alex K: that makes it sound like it may not be worth huge optimization? 11:44:46 AM Alex M: no, not really
- daleharvey 17y agomost of the time this certainly falls under pointless microptimisation, but if you are doing a complex web application with cpu intensive operations, it can be really handy to know how css is applied (and how reflow / redraw works) to help the user experience.
- jbox 17y agoSteve's final conclusion: “For most web sites, the possible performance gains from optimizing CSS selectors will be small, and are not worth the costs. ” http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/ http://www.stevesouders.com/blog/2009/03/10/performance-impa...
- rimantas 17y agoExactly. I have an obsession with "optimized" markup, that means avoiding unnecessary elements, ids and classes. Let's not forget that all this stuff sits in markup and gets downloaded on each request. Even if that does not add up to much, I still want to have my code "clean". There is one particular site that inspires me: http://camendesign.com/ http://camendesign.com/ — take a look, not a single id or class.
- jqueryin 17y agoHe did this, however, at the expense of convoluted selectors, pseudo-elements, and pattern matching. Personally, I don't find his implementation to be very clean. I guess it's better to have the mess in your closet than wide out in the open, though.
- arsduo 17y agoIt's not every day you can experience all the astonishment of overturning a fundamental assumption without any of the pain of forced changes. I enjoyed that conversation. (I'm Alex K, btw.) Thanks for all the comments, everyone! Very cool to have that post picked up by Hacker News.
- ableal 17y ago(from the header:) The Two Alexs Alexes? Alex's? Alexi? Alexim? In hackanonical form, Alexen. As in oxen, vaxen, boxen.
- goodside 17y ago"Alices", by analogy with "codex".
- techiferous 17y agoAs in regexen. :)
- riffraff 17y agoIIRC oxen is a vestigial dual (not plural) form, so quite appropriate.
- bdr 17y agoAccording to http://www.etymonline.com/index.php?term=ox http://www.etymonline.com/index.php?term=ox -- "Oxen is the only true survival in Mod.Eng. of the O.E. weak plural." From what I can tell, it looks like OE nouns could have either "strong" or "weak" declensions, and this is different from the dual form. Someone on another forum claims that "brethren" is another example.
- riffraff 17y agomay well be true, my source is an old State of the Onion talk from Larry Wall, which although a linguist is probably not the most qualified in the world :)
- bwill 17y agoCan anyone point to where this is required by the css specification? Or is this an implementation detail? The reality may be that all the browsers do it this way, but why couldn't someone add some more smarts to choose selectors based on selectivity, just as a SQL query planner would?
- robin_reala 17y agoIt’s quicker to walk up a DOM tree than it is to walk down - that’s the root reason why browsers have all implemented it this way.
- neilk 17y agoYeah, but if we do something like this: #alert > p { background: yellow } Surely the intelligent thing for the CSS engine is to look for the one-and-only #alert, rather than work backwards from all the <p>'s? (I am assuming that nodes with ids have their own fast index.)
- robin_reala 17y agoid attributes are unique in well formed pages, but then a lot of HTML is not well formed. Browsers do maintain a hashmap (or equiv) of id to node though, so in that case you’re right, that should be faster. Maybe the overhead of parsing and choosing multiple code paths is slower than just walking the tree?
- gizmo 17y agoIt's a little trickier when you do it left to right. Suppose you have a DOM tree like this: div #alert - p, p, p - div #alert - p [lots of children] - p - div #alert [lots of children] [right to left] In order to find all Ps with an #alert parent, you first get a set of all paragraph elements. Most likely a list of all paragraphs is kept in memory, so it can be enumerated quickly. Since DOM trees are generally well balanced the number of parents of any one paragraph is going to be roughly O( 2log(|DOMSIZE|) ) and it can be enumerated in C, so this is basically nothing (compared to how grossly inefficient javascript is). Total complexity: O( |P NODES| * 2log( |DOMSIZE| ) ). Memory complexity: 1 linked list of size of result set. [left to right] If we were to look at it from left to right, it gets trickier. You have to find all #alert nodes (easy & fast), but then you have to take all children of all #alert nodes. Every sub-tree of the DOM can be a significant fraction of the entire DOM tree, or perhaps the _entire_ dom tree. Not only that, but you CANNOT filter for all "p" children, because then you'd need to have lookup tables for every level in the tree (hugely inefficient). So you're left with one solution, that is to enumerate all children (and a DOM node can have a few thousand child nodes easily). But, wait, one #alert contains another #alert. We're already looking at O( |DOMSIZE| * |DOMSIZE| ), and now we have to consider uniqueness as well. We cannot alloc a hash map to keep track of uniqueness, because that would completely fragement your memory space; you'd end up allocating&deallocating hashmaps for every selector call. So you end up having to traverse the result set linked list for every node you add, to see if it isn't already in there. This, needless to say, is another O(N^2) detour. Total worst case complexity for M selectors: O( M * |DOMSIZE|^2 + M * |RESULTSET|^2 ). Memory complexity: M + 1 linked list. Difference becomes more profound as complexity increases: #uniq p p span b (R2L) find all "b" nodes, append those with matching parents to linked list. Return linked list (L2R) find all #uniq nodes, enumerate all "p" children. Make sure all "p" children are unique. Take all children of these "p" nodes, filter for "p" children, make sure result set is unique. Take all children of these "p" nodes, filter for "span", make sure.... and so it goes. So that's why.
- FluidDjango 17y agoThe "Two Alexes" are just discovering (Feb 2010) what Steve Souders explained in detail at http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/ http://www.stevesouders.com/blog/2009/06/18/simplifying-css-... [which is probably the site you want to visit on "How CSS strategies affect site performance"] (June 2009).
- tjic 17y agoBeing "scooped" by a mere 6 months, on a 10 year old technology doesn't really make their realization dated. It's new to me, and I bet it's new to most news.yc-ers.
- jrockway 17y ago/me mumbles something about Reading The Fine Source. Then you don't have to guess what your browser is doing.
- smackfu 17y agoTrying to figure out HTML from reading the Firefox source is kind of insane.
- jrockway 17y agoYeah, OK. So just be ignorant instead.
- etherealG 17y agodo you read the source of the linux kernel to understand how to use bash? how about the source of a wifi driver before connecting to a network? your premise is rediculous.
- jrockway 17y agoI don't do those things, but that's not because it's a bad method, but because I don't care. If there was some bug in some system call, or if I needed to investigate why hardware is misbehaving, of course I'd read the Linux source. That's one of the great things about open source software; you don't have to treat it like a black box. You can just look at the internals and see how they work. (And I have proof that I do actually do this; I had a misbehaving joystick, and the linux fork in my github contains the fix.) Anyway, in conclusion, if you want to know what algorithm Firefox uses to process CSS selectors, just read the Firefox source code. If you don't give a damn, then don't do that instead. But if you care and you do nothing, that's just silly.
- stanleydrew 17y agoGoogle describes this and a bunch of other great stuff about how to optimize page rendering: http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors http://code.google.com/speed/page-speed/docs/rendering.html#...
- Jim72 17y agoPlease, using more CSS selectors than DOMs isn't going to kill a site. In fact, it isn't even close to being a bottleneck. We are talking milliseconds. If you want speed gains, properly compress your images!
- jrockway 17y agoWait, are you saying that a computer capable of executing millions of instructions per second doesn't take very long to do a few comparisons on a dozen or so elements? It takes me a long time to do by hand, so I figured the computer would be really slow too!
- Tuna-Fish 17y ago> a computer capable of executing millions of instructions per second Billions, not millions.
- btilly 17y agoBillions of cycles per second. But executing an instruction frequently takes 20 cycles or so. That reduces instructions to hundreds of millions.
- jacoblyles 17y agoPresumably any modern processor would use some form of pipelining, which I think would take instructions back up into the billions. (The pentium 4, if I recall correctly, had a 20+ stage pipeline)
- gridspy 17y agoLong pipelines cause issues when branches get mis-predicted. The half processed instructions have to be thrown away. What you want is a CPU with a short pipeline, a fast clock rate and if possible instruction reordering and multiple dispatch. Large caches and good branch prediction help a lot too.
- smackfu 17y agoI do not like their blog gimmick.
- arsduo 17y agoFWIW, the post is a slightly cleaned up version of an actual conversation I had with my husband. (I'm K, he's M.) It's not a format I'm likely to reuse (or have used before), but it fit the occasion and captured very well our feelings of surprise at learning how CSS parses selectors. Plus, it's always fun to try out new formats, even -- or maybe especially -- if they don't stick.
- CoryMathews 17y agomicro optimization... blah. Why do I really doubt Alex's yoga site needs to worry about this.
- aw3c2 17y agoI don't want to read several pages of badly spoken chat english to find the conclusion. Could someone be so kind and explain what the shocking truth is?
- kellegous 17y agoIf you want to know how much CSS selector matching (sometimes called Style Recalculation) is affecting your site you can try Speed Tracer: https://chrome.google.com/extensions/detail/ognampngfcbddbfemdapefohjiobgbdl https://chrome.google.com/extensions/detail/ognampngfcbddbfe... It's Chrome-only but you can sometimes get cross-browser insights. It's also a lot easier to conduct a cursory investigation using this tool than it is to start changing your selectors.
- howcool 17y agoThis is not "News"
- scotty79 17y agoDon't think about how fast it is unless you have solid evidence that it is slow.
- scotty79 17y ago11:44:33 AM Alex K: that makes it sound like it may not be worth huge optimization? 11:44:46 AM Alex M: no, not really 11:44:56 AM Alex M: I’m a purist though 11:45:18 AM Alex M: so this makes my world Last two lines scares the hell out of me.
- jamesr 17y agoThe definitive guide to this was written by then-Mozilla dev Dave Hyatt: https://developer.mozilla.org/en/Writing_Efficient_CSS https://developer.mozilla.org/en/Writing_Efficient_CSS That's from April 21st, 2000 - almost a decade ago.
- eneveu 17y agoReminds me of how you may optimize your javascript DOM/style manipulations to avoid re-calculating the styles too often. It was mentioned in this Google I/O session on GWT performance: http://www.youtube.com/watch?v=q9hhENmVTWg#t=32m38s http://www.youtube.com/watch?v=q9hhENmVTWg#t=32m38s (slides located here: http://code.google.com/events/io/2009/sessions/MeasureMillisecondsPerformanceTipsWebToolkit.html http://code.google.com/events/io/2009/sessions/MeasureMillis... ) This is where Speed Tracer comes in handy ( http://code.google.com/webtoolkit/speedtracer/ http://code.google.com/webtoolkit/speedtracer/ )