代码之家  ›  专栏  ›  技术社区  ›  mjy

高效低效的CSS选择器(根据Google,PageSpeed…)

  •  10
  • mjy  · 技术社区  · 14 年前

    在试图减少网页的HTML大小时,我遇到了Google和PageSpeed Firefox插件重新获得CSS选择器效率的建议,这些建议(几乎)让我重新考虑了这些更改:

    http://code.google.com/intl/de-DE/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors

    具体来说,子代选择器非常适合使用ID或CLASS属性选择整个块(例如DIV),然后使其所有子元素不受CLASS/ID属性的影响。但如果应用规则的遍历顺序如Google所述,则不应使用它们:

    我非常怀疑浏览器使用这样一种低效的遍历顺序,它们肯定只会处理与顶级选择器组件匹配的元素子树,即 #foo span {...} 只应检查foo以下的元素,而不是每个跨度。查看过最近浏览器代码的人可以确认/拒绝这一点吗?

    第二个有问题的建议是关于过度合格的选人:

    根据定义,ID选择器是唯一的。包含标记或类限定符只会添加需要不必要地求值的冗余信息。

    div#foo{颜色:黑色;} #foo{颜色:白色;}

    将在 <div id=foo>

    有谁能与现代浏览器的源代码保持良好的关系来解释这些说法吗?由于大多数现代网站使用后代选择器(包括SO),而且它们有明显的优势,我非常想使用它们。。。

    我对生成的页面做了一些试验,看起来浏览器对后代选择器的处理确实很糟糕:

    由(缩写)组成的一页:

    #foo1 a.foo{颜色:红色;}

    #foo2 a.foo{颜色:红色;}

    <主体id=top>

    <

    [前一行重复10000次]

    (基本上是10000行,每个行有50个嵌套div,遍历到根节点,1个选择器匹配10000个)

    加载和渲染(直到 window.onload()

    .foo 类选择器从非应用规则中删除,Safari 5和Firefox 3.6.10的页面分别用200秒和96秒。这说明了子代选择器的实现有多糟糕(在这种情况下,10000条规则中的每一条都可能导致遍历,直到规则失败的顶部)。

    儿童选择者的待遇如何? #foo > span > div > div > div > div > div a {color: red;} (也从不匹配,但强制遍历6个父节点)Safari 5需要27秒,Firefox 3.6.10需要31秒。

    结论

    1 回复  |  直到 14 年前
        1
  •  8
  •   Moin Zaman    14 年前

    看看Jonathan Snook最近的这篇文章: http://snook.ca/archives/html_and_css/css-parent-selectors

    您将看到浏览器如何计算表达式,以及为什么某些选择器效率低下的原因。

    帖子中的相关引述:

    从右到左计算CSS。

    确定CSS规则 适用于特定元素,它 从规则的权利开始 走左边的路。

    如果你有一个像规则一样的身体 对于每一个元素 在页面上它会首先询问 一路向上爬然后问 这是一个有内容ID的div。如果 它会找到它想要的,它会 继续向上直到 到达尸体。

    通过从右向左工作,浏览器 对于这个特殊的元素 更快。确定哪条规则是 找出需要多少个节点 可以应用于元素。