web性能优化-简化css选择符

来源:互联网 发布:mcgs软件抢答器 编辑:程序博客网 时间:2024/05/21 17:40

1. 颠覆你我的认识:CSS匹配顺序】

首先看下如下规则:#toc > li { font-size: 14px; }

我们中的大多数人,尤其是那些从左到右阅读的人,可能猜想浏览器也是执行从左到右匹配规则的,因此会推测这条规则的性能开销并不高。在脑海中我们想象浏览器会像这样工作:找到唯一一个id为toc的元素,然后把这个样式应用到直系子元素中的li元素上。我们知道只有一个id为toc的元素,并且它只有几个li子元素,所以这个css选择符在性能表现上应该相当高效。

事实上,css选择符是从右到左进行匹配的。了解这方面的知识后,我们知道这个之前看似高效的规则实际开销相当高,浏览器必须遍历页面上每个li元素并确定其父元素的id是否为toc。

对于以下这个示例,性能表现上甚至更糟:#toc a { color: red; }

如果浏览器是从左到右读取的,按么它仅仅需要检查toc里的链接元素,实际上却检查了整个文档中的每个链接。然而,浏览器并不仅仅检查每个链接的父元素,还要遍历文档树去查找一个id为toc的祖先元素。如果被检索的链接不是toc的后代,那么浏览器就要向上一级遍历直到文档的根节点。

小结:

1. css选择符是从右到左进行匹配的。

2. 编写高效css选择符建议】

【避免使用通配符“*”】:

建议通配规则在样式初始化中仅进行一次匹配,更为推荐使用的是ID、类和标签选择符。

【不要限定ID选择符】:

在页面中一个指定的ID只能对应一个元素,所以没有必要添加额外的限定符。例如:div#toc是没必要的,应该简化为#toc。

【不要限定类选择符】:

不要用具体的标签限定类选择符,而是根据实际情况对类名进行扩展。例如:把li.captain改成.li-captain或是.list-captain更好。

【让规则越具体越好】:

不要试图编写像 ol li a 这样的长选择符,最好是创建一个类似于.order-list-anchor的类,并把它添加到适当的元素上,通过该示例不难看出,在编写规则时应该避免使用后代选择符,甚至更进一步避免使用子选择符。

【依靠继承】:

了解哪些属性可以通过继承而来,然后避免对这些属性重复指定规则。例如:对列表元素而不是每个列表项元素设置list-style样式。

小结:

1. 高效css选择符编写建议:【避免使用通配符“*”】、【不要限定ID选择符】、【让规则越具体越好】、【依靠继承】。

        

3. 关键选择符】

之前的示例其实说明到在某些情况下,即使复杂的css选择符在性能上的影响也能可能很小,不过情况并非总是如此,例:div div div p .captain,初看之下,这似乎是一个匹配开销很高的选择符,它是一个要匹配五级祖先元素的后代选择符。然而,回想下选择符是从右到左匹配的,我们就会认识到这个后代选择符执行速度和一个更简单的类选择符差不多。最右边的参数也叫关键选择符,它对浏览器执行的工作量起主要影响,在该示例中,关键选择符是.captain,页面中只有少量元素匹配这个关键选择符,所以匹配这个选择符所需要的时间是极少的。

小结:

1. 决定css选择符是否高效,“关键选择符”的设置至关重要。

4. 回流时间】

对于web2.0应用来说,更应该考虑当用户和网页交互时,浏览器应用样式和布局元素所花费的时间,这段时间消耗可称为“回流时间”。当使用javascript修改dom元素样式的某些属性时会触发回流,例:ele.style.display = “none”,ele.style.padding = “10px”... web2.0应用的动态性令其很容易就触发回流,所幸的是回流并不需要涉及到页面上所有的元素,浏览器已经为此进行了优化,仅仅只对那些受回流影响的元素重新布局。因此如果是对body或是包含很多后代元素的结构,回流的开销将会相当高。

回流需要重新应用css规则,这意味着浏览器必须再次匹配所有的css选择符。如果选择符是低效的,那么回流时间消耗必然可观,如果javascript对样式属性有操作,且页面开始变慢,那么低效的css选择符就很可能是罪魁祸首。

最后不得不说,任何解决方案都可能是把双刃剑,将每个受影响元素的后代选择符替换成类选择符,不仅会增加页面大小,还会降低样式的灵活性,不过个人认为优化css规则还是利大于弊的。

小结:

1. 浏览器应用样式和布局元素所花费的时间称为“回流时间”。

2. 编写高效css选择符的宗旨:尽可能地减少样式规则匹配次数。

本文来源http://bbs.itsource.cn/thread-1548-1-1.html