更快的两个CSS规则:指定/不指定多个ID

时间:2011-01-24 05:18:59

标签: css performance dom css-selectors

所以我最近在使用Concrete5做了很多工作。但是,我注意到默认主题有许多 CSS规则,其定义如下:

#page #central #sidebar p{line-height:24px}

由于“侧边栏”是一个ID,整个页面上应该只有一个“侧边栏”(假设它有效,我正在照顾它)。因此,如果#sidebar位于#page #central,则{strong>始终应位于#page #central。无论。在每一页上。

通过这种逻辑,以下规则完全相同:

#sidebar p{line-height:24px}

测试这一点,果然,它有效。所以我的问题是 - 哪个会有更好的表现?是否存在与速度相关的原因,即Concrete5团队采用更长的规范,还是仅仅是为了帮助未来的开发人员找到#sidebar div?在任何一种情况下,我都可以看到它的论点更快。

如果案例1更快(#page #central #sidebar):

如果浏览器使用广度优先搜索算法来定位正确的DOM元素,那么查找#sidebar将涉及在到达之前搜索具有子元素的 EVERY DOM元素的第二层第三层,此时它在查找#sidebar之前仍然会看到几个元素。通过以这种方式指定元素,广度优先搜索将识别#page并且知道它只需要继续在该元素内搜索,而不是继续使用整个DOM。

如果案例2更快(#sidebar):

如果浏览器按照它编写的顺序搜索整个文档,而不是像树一样处理DOM,那么它将执行单个线性搜索而不是三个线性搜索。实际上,即使在最好的情况下,它足够聪明地识别先前找到的DOM元素的起点和终点(本质上是深度优先搜索),它仍然必须读取尽可能多的代码行。线性搜索 - 首先它会在找到#page之前读取,然后它会从#page的开头开始读取,直到找到#center,然后它会从{{{}开始读取1}}直到找到#center。唯一的区别是从一个搜索切换到另一个搜索所涉及的微量开销

4 个答案:

答案 0 :(得分:4)

AFAIK没有可行的方法来测试浏览器CSS匹配算法的速度,就速度而言,#page #central #sidebar#sidebar之间的差异可以忽略不计,不值得担心。

值得担心的是specificity中的差异。

有时候值得在选择器中添加一个额外的id / class /元素,以确保在以后的级联中使用简单的选择器不会错误地覆盖该样式。

#page #central #sidebar p的特异性为3-0-1,而#sidebar p的特异性为1-0-1,这意味着#page #central #sidebar p优先。

另外,你提到了:

  

...如果#sidebar位于#page #central,则应始终位于#page #central。无论。在每一页上。

情况并非如此,了解原因非常重要。仅仅因为id是唯一的,并不意味着它必须遵循每页上完全相同的页面结构。

例如:流行的内容管理系统(Drupal)允许开发人员为不同页面的不同区域上的块放置指定规则。我可能希望#search-block位于首页上的#header,然后位于所有其他页面中的#sidebar。使用更具体的选择器将允许我根据其父容器给出#search-block不同的样式。

答案 1 :(得分:4)

简短的故事:你使用的东西越多,解析的速度就越慢。

ID始终是唯一的,因此您应该只使用一个;但即使是课程,指定任何其他元素或标准总是会变慢。

http://css-tricks.com/efficiently-rendering-css/

这篇文章更深入地探讨了你所要求的内容。

答案 2 :(得分:1)

除了性能问题,这些并不总是转化为同样的东西

#header {
   background: blue;
}

#home #header {
   background: red;
}

这是对级联的完全有效使用,使一个页面看起来与另一个页面不同。我一直使用这种模式,通常是因为我将classid分配给我的body元素,作为CSS和JavaScript的钩子。

答案 3 :(得分:1)

我不知道性能,也不关心,但是将多个ID选择器放在一起肯定意味着与仅使用一个ID选择器不同,而且我很确定人们不会出于性能原因而将这样的选择器链接起来更多比什么都重要。

#page #central #sidebar p

如果p位于#sidebar内的#sidebar#central中只会找到#page。因此不会找到这些#sidebar s:

<body>
    <div id="sidebar"></div>
</body>

<body>
    <div id="page">
        <div id="sidebar"></div>
    </div>
</body>

<body>
    <div id="central">
        <div id="sidebar"></div>
    </div>
</body>

同样,不确定性能,但当然浏览器必须在这里做更多的工作,因为它必须检查每个元素的DOM层次结构,因为它从右到左解析这个选择器。这是真正的原因;如果你的CSS说明#sidebar样式,只有在#page #central中找到它时,浏览器才会在尝试应用样式之前进行这些检查。

#sidebar p

这会在p中找到#sidebar { #sidebar中的

另外,也许我误解了你的问题,但对此:

  

由于“侧边栏”是一个ID,整个页面上应该只有一个“侧边栏”(假设它有效,我正在照顾它)。因此,如果#sidebar位于#page #central,则{strong>始终应位于#page #central。无论。在每一页上。

不,不总是。您可以将#sidebar置于任意位置,只有当所有三个ID的选择器选择#sidebar 时才会选择<{1}} #page #central满足您假设的唯一方法是确保标记的结构如此。您的样式不能也不会知道您的标记,特别是如果它被用于在网站上设置多个页面的样式。

话虽如此,如果您可以确保您的标记在该结构中始终包含#page #central #sidebar,那么单独选择#sidebar就没有问题。我的观点是,不同的选择器意味着不同的东西,而且你不仅仅是出于性能原因选择其中一个 - 更常见的是它不会超出这个范围。