在尝试降低网页的HTML大小时,我遇到了Google和PagesPeed Firefox加载效率的CSS选择器的建议,这些效率(几乎)使我重新考虑了更改:

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

具体而言,后代选择器非常适合使用ID或类属性选择整个块(例如DIV),然后将其所有子元素保持不含类别/ID属性。但是,如果按照Google的描述,则不应使用它们的遍历顺序,则不应使用它们:

后代选择器的效率低下,因为对于匹配键的每个元素,浏览器还必须穿越DOM树,评估每个祖先元素,直到找到匹配或达到根元素为止。键的特异性越少,需要评估的节点数量就越大。

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

第二个可疑建议是关于过度合格的选择者:

根据定义,ID选择器是唯一的。包括标签或类限定符仅添加需要不必要评估的冗余信息。

如果ID选择器根据定义是唯一的,那么为什么浏览器需要检查冗余信息?我知道他们这样做是因为

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

将导致黑色文字 <div id=foo>, ,但是a)不应该完成(需要?W3C参考)和b)我不明白为什么当它导致简单的O(1)检查元素的标签名称时,它会明显慢。

任何人都可以通过现代浏览器的源代码对这些说法有所了解吗?由于大多数现代网站都使用后代选择器(包括SO),并且它们具有明显的优势,因此我非常喜欢使用它们...

编辑:

我已经对生成的页面进行了一些实验,看来浏览器对后代选择器的处理确实是可怜的:

一个包含(缩写)的页面:

#top a {text-decoration:none;}

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

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

...重复10000次

u003Cbody id=top>

u003Cdiv>... [嵌套50次] u003Ca href=foo>BLAu003C/a>u003C/div> [...

以前的行重复10000次

(基本上是10000行,每个嵌套为50个嵌套div,直到根节点和1个匹配10000的选择器)

负载和渲染(时间到 window.onload() 使用Safari 5在2.2秒内执行),而Firefox 3.6.10则不到10秒。

当。。。的时候 .foo 从非应用规则中删除了类选择器,该页面大约需要200秒,而Safari 5和96秒,Firefox 3.6.10。这说明了后代选择器实现的严重程度(在这种情况下,10000规则中的每一个可能导致遍历直到规则失败的#top)。

儿童选择者如何票价? #foo > span > div > div > div > div > div a {color: red;} (也永远不会匹配,但力量遍历6个父节点)需要27秒,而Safari 5和31秒,Firefox 3.6.10。

结论

后代和儿童选择者目前都在主要的浏览器上吸吮。如果您关心速度,至少对于非常常见的HTML标签(例如A,IMG,DIV等),则最好在所有样式标签中添加丑陋的类/ID属性。

有帮助吗?

解决方案

看看乔纳森·斯诺克(Jonathan Snook)最近的这篇文章: http://snook.ca/archives/html_and_css/css-parent-selectors

您将看到浏览器如何评估表达式以及某些选择器效率低下的原因背后的推理。

帖子中的相关报价:

CSS从右到左进行评估。

为了确定CSS规则是否适用于特定元素,它从规则的右侧开始,并起作用。

如果您有一个规则,例如Body Div#内容P {颜色:#003366; }然后,对于每个元素(将其渲染到页面),它首先询问它是否是段落元素。如果是这样,它将在DOM上运行,并询问它是否是具有内容ID的DIV。如果它找到了想要的东西,它将继续沿着DOM延伸直到到达身体。

通过向右工作,浏览器可以确定规则是否适用于试图更快地绘制到视口的特定元素。要确定哪个规则或多或少的性能,您需要弄清楚需要评估多少个节点,以确定是否可以将样式应用于元素。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top