css选择器: 编写高效的CSS选择器

高效的CSS已经不是一个新话题,也不是一个我非得重拾的话题,但是,它却是自我在SKY工作以后,真正感兴趣并始终关注的一个话题。
很多人或者忘记了,或者仅仅是没有意识到,CSS可以是高效的也可能导致低能。然而,我们可以不考虑当你自认为会的太少而使用了低效的CSS这种情况。
这些规则只真正用在性能要求很高的网站上,这些网站对速度要求很高,任何一个页面可能含有成百上千个DOM元素。但是实践出真理,不管你是在打造下一个facebook 还是在开发一个本地的展示网页,多学点总是好的....
CSS 选择器
CSS 选择器对我们大多数人来说并不新鲜,较基础的选择器分别是类型(如 div),ID(如#header)和类(如.tweet)。
较不寻常的包括基础的伪类(如:hover)和更复杂的CSS3以及 '正则'(‘regex’)选择器,比如:first-childor[class^="grid-"]。
选择器具有固有效率,引用Steve Souders的话来说,较有效到较不有效的CSS选择器的顺序是这样的:
ID,如#header
Class, 如.promo
Type, 如div
Adjacent sibling, 如h2 + p
Child, 如li > ul
Descendant,如ul a
Universal,即*
Attribute, 如[type="text"]
Pseudo-classes/-elements, 如a:hover
引用自Steve Souders的Even Faster网站
认识这很重要,虽然一个ID技术上更快而且表现更优,但几乎都不这样用。用Steve Souders的CSS测试器,我们可以发现一个 ID 选择器 和 一个类选择器 在再渲染速度方面差别很小。
在一台Windows机器上的Firefox6中,我获得了关于一个简单的类选择器的平均再渲染数据。ID选择器给出了12.5的平均值,所以实际上它要比一个类再渲染得慢一点。
ID与类之间的速度差异几乎是不相干的。
对一个类型(<a>)的选择测试,相比一个类或ID给出了慢得多的再渲染。
对一个层次非常多的子孙选择器的测试给出了 大约440的数值!
通过这我们可以发现IDs/classes与types/descendants的差别非常巨大...它们自身之间的差异很细微。
注意 这些数值在不同的机器和浏览器变化非常大。我极力建议你自己运行一下。
组合选择器
你可以单独使用一种标准选择器,如#nav,来选择所有以"nav"为ID的元素,你也可以使用组合选择器,如#nav a,来选择任何在ID为’nav’的元素里面的链接元素。
现在,我们从左到右读这个组合标签。我们先找到#nav ,然后再找到里面的元素。但是我们的浏览器不是这样解析的,它是从右到左来解析这些组合选择器的。
当我们看到#nav里面有个a,而浏览器看到的却是有个a在 #nav里面,这些细微的差异对浏览器的性能有重大影响,同事学习他们是很有价值的。
如果想知道浏览器这样解析的原因,请参考this discussion on Stack Overflow.
对浏览器来说,从最右边的元素(它最想渲染的元素)开始,然后回溯到DOM树比从DOM树的最高层开始选择向下寻找,甚至可能达不到最右边的选择器(关键的选择器)要高效。
这对CSS选择器的性能有重大影响....

关键选择器
这里讨论的关键选择器, 是处在复杂选择器最右端的选择器,也是浏览器最先解析的选择器。
让我们回到讨论开始的地方,哪种选择器最高效?哪种选择器作为关键选择器会影响选择器的性能;当我们书写CSS代码的时候,正是这个关键选择器影响选择器的效率。
一个关键选择器是这样的:
#content.intro{}
天生高效选择器如类型选择器是不是就会有更高的性能?浏览器会寻找.Intro的所有实例(数量不会很多),然后向上查找DOM树,以确定该关键选择器是否在以“content’”为ID的元素里面。
然后,以下的选择器性能就不怎么好了:
#content*{}
这个选择器做的工作是这样子的,它先查找每个页面(是每个单个的页面),然后去看看它们是否有一个 #content 的父元素。这是一个非常不高效的选择器,因为它的关键选择器执行开销太大了。
运用这些知识我们就能在分类和选择元素时做更好的选择。
 
假设我们有一个非常庞大的页面,非常的大并且是一个还有一个庞大的网站。在这个也面上,有上百甚至上千哥<a>标签。社交媒体的链接只占很少的一部分,并且包含在ID为#social的<ul>里面。假设这些链接是,Twitter, facebook, Dribble 和 Google+。我们在这个页面上有四个社交媒体链接,还有上百个其他的链接。
以下这个选择器代价很高而且性能不好:
#social a{}
浏览器将访问扫描页面上的上千个链接,然后才选择上#social节点下的四个链接。我们的关键选择器匹配了大量的我们并不感兴趣的标签。
为了消除这个问题,我们可以为每一个包含在社交媒体<ul>块下面的<a>标签指定更明确和显式的选择器.social-link。但是这跟我们所知道的恰恰相反;我们知道了,当我们使用精简的标签的时候,尽量不要使用多余的类。
 
这就是为什么我觉得性能是如此的有意思;在网页标准最佳实践和速度之间,需要一个平衡。
我们通常会这么写:
<ul id="social">
<li><a href="#" class="twitter">Twitter</a></li>
<li><a href="#" class="facebook">Facebook</a></li>
<li><a href="#" class="dribble">Dribbble</a></li>
<li><a href="#" class="gplus">Google+</a></li>
</ul>
CSS:
#social a{}
现在我们改为:
<ul id="social">
<li><a href="#" class="social-link twitter">Twitter</a></li>
<li><a href="#" class="social-link facebook">Facebook</a></li>
<li><a href="#" class="social-link dribble">Dribbble</a></li>
<li><a href="#" class="social-link gplus">Google+</a></li>
</ul>
对应的CSS:
#social .social-link{}
这是一个全新的关键选择器,匹配更少的元素,意味着浏览器可以更快地找到它们并给它们赋予样式。
同时,实际上,我们可以进一步精简选择器,使用.social-link{},而不需要过渡的约束它;阅读下一章节来了解详情。
所以,概括的说,你的关键选择器是其中一个决定浏览器的工作量,所以你需要好好的留意它。
过度修饰的选择器
现在我们已经了解了关键选择器是什么,它是后续工作的基础,我们现在来看看如何进一步优化它。使用更明确的关键选择器就是,你需要避免过度使用修饰选择器。以下是一个过度修饰的选择器:
1 html body .wrapper #content a{}

这个选择太啰唆,起码有三个选择器是完全没必要的。精简样式应该为:
#content a{}
那又如何?
这意味着浏览器需要扫描所有的标签,检查它里面是否包含一个ID叫做“content”的标签,如此在html标签中不停查找。这样会导致浏览器做了多余的检查工作,并且是完全没必要的工作。知道了这点后,我们可以看看下面更接近实际的例子:
#nav li a{}
精简为:
#nav a{}
我们知道如果标签a在li标签里面,li标签又在#nav里面,那么我们可以从选择器中去掉li。然后,因为nav拥有一个ID,这个ID是唯一的,所以它赋予的元素是完全不相干的,我们可以去掉ul。
过度修饰的选择器会导致浏览器需要做更多的工作;从选择器中去除不必要的部分,让你的选择器更简洁,性能更高吧。
所有这些都是必要的吗?
简短的答案是:可能不是。
长一点的答案是:它依赖于你正在创建的网站。如果你在做你的下一个作品,那么超越CSS选择器性能去追寻干净的代码吧,因为你其实并不想关注它。
如果你在创建下一版的Amazon, 而页面速度的微秒变化确实会有不同,那么可能需要,但即使那样也可能不。
浏览器只会在CSS解析速度方面越来越好,甚至移动浏览器也一样。你很可能从来也不会注意到浏览器中的很慢的CSS选择器,但是...
但是
它仍然正在发生着,不管浏览器有多么快,它们仍然必须做所有我们谈论到的工作。即使你不需要甚至不想实施其中任何一条,它当然仍是值得知道的东西。记得选择器可能会代价很高,还有你应该在可能的地方避免使用代价更大的选择器。那意味着,如果你发现自己写了一些东西诸如:
div:nth-of-type(3) ul:last-child li:nth-of-type(odd) *{ font-weight:bold }
那么可能你做得不对。现在我自己在高效选择器的世界也是一个新手,因此如果我遗漏了什么,或者你有什么需要添加的,请在评论里发表它!
更多关于高效的CSS选择器
我怎么推荐Steve Souders的网站与书也不过分。对你需要的延伸阅读来说,那足够了。这伙计知道的很多!

本文链接http://www.cxybl.com/html/wyzz/CSS/20130915/40122.html

时间: 2024-10-03 21:36:23

css选择器: 编写高效的CSS选择器的相关文章

css知多少(5)——选择器

原文:css知多少(5)--选择器 1. 引言 从本节开始,就进入本系列的第二个部分--css和html的结合--说白了就是选择器. CSS中定义了样式,如何将这些样式设置到相应的html节点上?就不得不通过选择器.让浏览器知道css选择了哪一个dom节点,浏览器就会乖乖的把相应的样式渲染成视图. 至于css能把页面渲染成什么样子,这是本系列的第三部分. 第一部分讲css样式的加载和层叠,第二部分讲选择器以及选择器的等级,第三部分讲呈现的各种样式(背景.字体.定位.浮动等).这样一个思路,也正式

css知多少(6)——选择器的优先级

原文:css知多少(6)--选择器的优先级 1. 引言 上一节<css知多少(5)--选择器>最后提到,选择器类型过多将导致一些问题,是什么问题呢?咱们直接举例子说明. 上图中,css中的两个选择器都是针对<span>的,而且两个设置的颜色不一样,这里的<span>到底听从谁的命令? 上面还是比较简单的,下面在来一个复杂的: 上图中的<li>该显示成什么颜色呢? 2. 特指度 要解决以上问题,我们需要引入一个概念--特指度(specificity).特指度表

CSS开发框架技术OOCSS编写和管理CSS的方法

文章简介:今天最流行的CSS开发框架技术当属OOCSS,尽管还有其他类似的技术存在,如BEM.这些方法试图对CSS采用面向对象的编程原则.尽管样式语言和面向对象的软件设计原则在概念之间存在一定的问题,这些微妙的东西对于一个欠缺经验的开发人员来说可能不会立即显现出来.最令人不 公认的拥有一个编写和管理CSS的方法比什么都要更好.尽管如此,一些开发人员的实践是不利于语义化质量和长期的可维护性.我们要讨论一些被提倡的"CSS框架方法"的问题和作为Web开发人员,我们如何可以更好的解决这些问题

如何使CSS渲染更高效

我承认我并不经常想这个问题......我们写的css的效率是怎么样的呢,浏览器渲染的速度又如何呢? 这是应该是浏览器开发者应该关心的(页面加载更快,用户就会更愉快).Mozilla有一篇文章:about best practices . Google当然也很关心这个问题,他们也有这样一篇文章:Optimize browser rendering . 让我们了解下他们主要倡导的东东,然后讨论他们的实用性. 从右到左 浏览器如何读取你的CSS选择器有一个很重要的原则,那就是它们从右到左读取.这意味这

高效整洁CSS代码

CSS学起来并不难,但在大型项目中,就变得难以管理,特别是不同的人在CSS书写风格上稍有不同,团队上就更加难以沟通,为此总结了一些如何实现高效整洁的CSS代码原则:   1. 使用Reset但并非全局Reset 不同浏览器元素的默认属性有所不同,使用Reset可重置浏览器元素的一些默认属性,以达到浏览器的兼容.但需要注意的是,请不要使用全局Reset: *{ margin:0; padding:0; } 这不仅仅因为它是缓慢和低效率的方法,而且还会导致一些不必要的元素也重置了外边距和内边距.在此

让代码飞一会儿:快速编写 HTML 和 CSS 的工具和技术

你曾经考虑过想要加快 HTML 和 CSS 编码速度吗?不管你是否想过,都来看看这篇文章吧,你会从中学到很多东西.我们要讨论的不是 CSS 网格框架,也不是 CSS Reset.在这篇文章中,我们关注的是不同寻常的编码方式--CSS 编译器以及 HTML 缩写编码技术.借助这些优秀的工具和技术,能够大大的减少开发时间,加快开发进度. HTML 加快 HTML 编码的方法有很多,这里我们要介绍的是 HTML 缩写技术.取代传统的编写完整 HTML 标签,我们只需要编码缩写代码就能扩展到完整的HTM

CSS教程:编写易于管理的css

越来越多的大型网站开始关注.使用css,对于管理多个复杂css文件显然是有异议的.下面是二系列内容中的第一部分,第一部分我们关注对于管理样式的观点,并在其基础上总结出可行的方案.第二部分我们将对以上结论进行对比.强大的css技术最近几年已经被广泛推广了.感谢Wired redesign(以及后来的high profile redesigns-,更多组织)和CSS Zen Garden(禅意花园).除此之外,有越来越多的设计师加强了对于css的学习,并通过学习让工作更容易.简单,或者他们本身就是?

CSS代码编写技巧

CSS代码编写的两则小技巧 在一行内声明CSS 我们来对比下面两段代码: h2 {font-size:18px; border:1px solid blue; color:#000; background-color:#FFF;}h2 {font-size:18px;border:1px solid blue;color:#000;background-color:#FFF;} 第二种看起来的确格式化,但是不会在阅读上有任何帮助.写在一行内可以让你更快的找到需要的部分. 以前我也是写成类似第二种

javascript编写实用的省市选择器

 这篇文章主要介绍了javascript编写实用的省市选择器的方法及示例分享,非常不错,推荐给有相同需求的小伙伴们.     省市选择器是大家经常用到的, 但网上找的省市选择器都不是很实用,于是自己写了移动端的省市选择器. 界面: 源码结构:   演示地址:http://component.cform.cn/city/ 演示二维码: 源码地址:http://component.cform.cn/city/city.zip