`

编写高效的CSS选择器 (转)

    博客分类:
  • css
 
阅读更多

高效的CSS已经不是一个新的话题了,也不是我一个非得重拾的话题,但它却是我在Sky公司工作之时,所感兴趣的,关注已久的话题。

有很多人都忘记了,或在简单的说没有意识到,CSS在我们手中,既能很高效,也可以变得很低能。这很容易被忘记,尤其是当你意识到你会的太少,CSS代码效率很低的时候。

下面的规则只真正被应用到那些速度要求很高,有成百上千的DOM元素被绘制在页面上的大型网站。但是,实践出真理,这和你是在创建下一个Facebook,还是写一个本地的展示页面都没有关系,多知道一点总是好的。

CSS选择器:

对我们大多数人来说,CSS选择器并不陌生。最基本的选择器是元素选择器(比如div),ID选择器(比如#header)还有类选择器(比如.tweet)。

一些的不常见的选择器包括伪类选择器(:hover),很多复杂的CSS3和正则选择器,比如:first-child,class ^= “grid-”.

CSS选择器具有高效的继承性,引用Steve Souders的话, CSS选择器效率从高到低的排序如下:

1.ID选择器 比如#header

2.类选择器 比如.promo

3.元素选择器 比如 div

4.兄弟选择器 比如 h2 + p

5.子选择器 比如 li > ul

6.后代选择器 比如 ul a 7. 通用选择器 比如 *

7.属性选择器 比如 type = “text”

8.伪类/伪元素选择器 比如 a:hover

以上引用自Steve Souders的Even Faster网站、

我们不得不提的是,纵使ID选择器很快、高效,但是它也仅仅如此。从Steve Souders的CSS Test我们可以看出ID选择器类选择器在速度上的差异很小很小。

在Windows系统上的Firefox 6上,我测得了一个简单类选择器的(reflow figure)重绘速度为10.9ms,而ID选择器为12.5ms,所以事实上ID比类选择器重绘要慢一点点。

ID选择器和类选择器在速度上的差异基本上没有关系。

在一个标签选择器(a)的测试上显示,它比类或ID选择器的速度慢了很多。在一个嵌套很深的后代选择器的测试上,显示数据为440左右!从这里我们可以看出ID/类选择器 和 元素/后代选择器中间的差异较大,但是相互之间的差异较小。

注意: 这些数据可能在不同计算机和浏览器中间的差异较大。强烈地建议大家在自己的机子上测试一下。

组合选择器

你可以有一个标准的选择器比如 #nav,来选择任何带有ID为”nav”的元素,或在你可以有一个组合选择器比如#nav a,来选择任何在ID为’nav’的元素里面的链接元素

此刻,我们读这些是从左到右的方式。我们是先找到#nav,然后从它的里面找其他元素。但是浏览器解析这些不是这样的:浏览器解析选择器是从右到左的方式。

在我们看来,#nav里面带了一个a,浏览器却是看到的a在#nav里面。这些细微的差异对选择器的效率有很大的影响,同时学这些差异也是很有价值的。

如果想要知道更多浏览器这样解析的原因,请看Stack Overflow上的讨论

浏览器从最右边的元素开始(它想要渲染的元素),然后用它的方式回溯DOM树比从DOM树的最高层开始选择向下寻找,甚至可能达不到最右边的选择器—关键的选择器要高效。

这些对CSS选择器的效率有很大的影响。

关键选择器

关键选择器,正如前面讨论的一样,是一个复杂的CSS选择器中最右边部分。它是浏览器最先寻找的。

现在我们回到讨论开始的地方,哪类选择器是最高效的?哪个是会影响选择器效率的关键选择器;写CSS代码的时候,关键选择器是能否高效的决定因素。 一个关键CSS选择器像这样:

#content .intro {..} 

是不是高效选择器比如类选择器天生就高效?浏览器会寻找.intro的实例(可能会很多),然后沿着DOM树向上查找,确定刚才找到的实例是否在一个带有ID为”content”的容器里面。

但是,下面的选择器就表现的不是那么好了:

#content * {..} 

这个选择器所做的是选择所有在页面上的单个元素(是每个单个的元素),然后去看看它们是否有一个 #content 的父元素。这是一个非常不高效选择器因为它的关键选择器执行开销太大了。

运用这些知识我们就可以在分类和选择元素的时候做出更好的选择。

假 设你有一个复杂的页面,它相当巨大并且在你的一个很大很大的站点上。在那个页面上有成百上千甚至上万的 a 标签。它还有一个小的社交链接区域放在一个ID为#social的Ul里面。我们假设它们是Twitter,Facebook,Dribbble还有 Google+的链接吧。在这个页面上我们有四个社交链接和成百上千的其他链接。 下面的这个选择器就自然的不是那么高效和合理了:

#social a {…} 

这里发生的情况是浏览器会在定位到#social区域下的四个链接之前得到页面上所有成千上万的链接。我们的关键选择器匹配了太多我们不感兴趣的其他元素。

为了补救我们可以给每个在社交链接区域的 a 增加一个更特殊、明确的选择器 .social-link , 但是这好像有点违背我们的认知:当我们能用组合选择器的时候就不要放不必要的类标示在元素上。

这就是为什么我对选择器的性能如此感兴趣的原因了:必须在web 标准最佳实践和速度之间的保持平衡。

通常我们有:

<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{}更清晰的选择,而不是过分限制它。阅读下一部分你会原因…

简单的重述一次,你的关键选择器会决定浏览器的工作量,因此,我们应该重视一下关键选择器

过度限制选择器

现在我们知道了什么是关键选择器,还有它是大部分工作的来源,但是我们可以更乐观一点。拥有一个明确的关键选择器最大的好处就是你可以避免使用过度限制选择器。一个过度限制选择器可能像:

html body .wrapper #content a {} 

这里的写的太多了,至少3个选择器是完全不需要的。它可以最多像这个样子:

#content a {} 

这会发生什么呢? 首先第一个意味着浏览器不得不寻找所有的 a 元素,然后检查他们是否在一个ID为”content”的元素中,然后如此循环直到HTML标签。这样造成了太多的我们不太想要的花费。了解了这个,我们得到一些更现实的例子:

#nav li a{} 

变成这个:

#nav a {} 

我们知道如果a在li里面,它也必定在#nav里面,所有我们可以马上把li从选择器组中拿掉。然后,既然我们知道在页面中只有一个ID为nav的元素,那么它依附的元素就是完全没有关系得了,我们也可以拿掉ul

过度限制选择器使浏览器工作比它实际需要的更繁重,花费的时间更多。我们可以删掉不必需的限制,来使我们的选择器更简单和高效。

这些真的需要吗?

最短的答案是:或许不是。

最长的答案是:它取决于你正在搭建的站点。如果你正在为你的晋升而努力,那么就好好写出简单、高效的CSS代码吧,因为你可能不会感觉到它给你带来的改变。 如果你正在搭建下一个每个页面都以毫秒计算的Amazon网站,这样有时速度会很快,但有时可能不是。

浏览器将会在解析CSS的速度上变得更好,甚至在手机端。在一个网站上,你不太可能会觉察到一个低效的CSS选择器,但是….

但是

它确实发生了,浏览器还是不得不去做我们讨论的所有工作,无论它们变得多快。即使你不需要或者甚至不想实践任何一个,但是它都是我们值得学习的知识。请记住选择器可能会让你付出很大代价,你应该避免盯着一个看。这意味着如果你发现你自己在写像这样的:

div:nth-of-type(3) ul:last-child li:nth-of-type(odd) *{ font-weight:bold } 

这时,你可能就做错了。

现在,在高效选择器的世界我还是一个新人。所以如果我忘记了什么,或者你有需要补充的,请在评论里面留言。

更多高效选择器

我还不能完全介绍Steve Souders的网站和书籍(《更快速网站》、《高性能网站》),它们是如此之好,以至于值得你花更多时间来阅读和推荐。这个家伙只有他自己才了解自己!

分享到:
评论

相关推荐

    react-React组件的css选择器

    在React开发中,CSS选择器是用于特定于组件的样式化的一种强大工具。React组件的样式管理是一个关键的方面,...同时,理解CSS选择器的工作原理和优先级,以及如何优化性能,对于创建高效、可维护的React应用至关重要。

    树使用css选择器优化代码(IE7+,firefox3,opera9,chrom下可用)

    高效的CSS选择器能够提高页面渲染速度,优化用户体验,特别是在处理大型或者复杂的页面结构时显得尤为重要。本篇文章将探讨如何使用CSS选择器来优化代码,使之适用于IE7+、Firefox 3、Opera 9以及Chrome等主流浏览器...

    一种可视化的方式来分析选择器在CSS中的特殊性

    总结来说,理解CSS选择器特殊性对于编写高效且易于维护的CSS至关重要。"Specificity Visualizer"是一个实用的工具,它将抽象的特殊性概念转化为直观的视觉表现,有助于开发者提升CSS布局控制的能力。在实际工作中,...

    前端css选择器练习diner.zip

    "前端css选择器练习diner.zip" 是一个针对CSS选择器学习和实践的资源包,名为"css-diner"。 在"css-diner"这个练习中,你可以深入理解并掌握各种CSS选择器的用法,从而提升你的前端开发技能。以下是一些关于CSS选择...

    jQuery 遍历css选择器

    其中,jQuery的CSS选择器是其核心功能之一,它提供了丰富的选择器来帮助开发者高效地选取页面上的元素。这篇教程将深入探讨jQuery如何遍历CSS选择器,并从中提取出相关知识点。 **一、jQuery选择器概述** jQuery...

    CSS选择器权重计算及优先级

    权重计算的规则确保了设计师能够...总的来说,理解并熟练掌握CSS选择器权重计算是编写高效且可维护CSS代码的关键。通过合理设计选择器,可以确保样式按预期应用,同时避免不必要的权重竞争,使CSS代码保持整洁和清晰。

    高效的CSS选择器编写指南

    《高效的CSS选择器编写指南》 CSS选择器的效率对于网页性能有着显著的影响,尤其是在处理大量DOM元素的大型网站上。CSS选择器的正确使用能够提高页面加载速度,提升用户体验。以下是一些关于CSS选择器效率和编写...

    CSS3选择器总结CSS3选择器总结

    CSS选择器可以分为多种类型,包括id选择器、类选择器、标签选择器、交叉选择器、群组选择器、后代选择器和通用选择器。 - id选择器:通过元素的id属性来选择特定元素,使用#符号加上id名作为选择器(如#idname)。 ...

    书写高效的CSS

    随着Web技术的发展与网站复杂度的提升,编写高效的CSS成为了前端工程师的一项必备技能。本文将根据mozilla开发者论坛中一篇关于Firefox浏览器架构的文章展开讨论,探讨如何通过优化CSS编写方式来提高浏览器的执行...

    第九课 css选择器-011

    在前端开发中,CSS(Cascading Style ...总之,CSS选择器是CSS的核心,熟练掌握它们能帮助开发者更高效、更精准地控制页面样式。通过合理使用不同选择器的组合和理解优先级规则,可以创建出更优雅、更灵活的CSS代码。

    很不错的CSS练手文件代码,应用多种选择器

    下面,我们将详细探讨这些重要的CSS选择器及其应用场景。 1. 基本选择器: - **类型选择器**:例如`div`、`p`,通过元素名来选择特定类型的元素。 - **类选择器**:以点`.`开头,如`.myClass`,用于选取具有指定...

    十种CSS选择器详解介绍

    ### 十种CSS选择器详解介绍 #### 一、通用选择器 - **定义**: 通用选择器使用星号 `*` 来表示,能够匹配HTML文档中的每一个元素。 - **示例**: ```css * { margin: 0; padding: 0; } ``` - **用途**: 常用于...

    30个你不可不知的CSS选择器小结

    CSS选择器是网页样式表语言(CSS)中的关键部分,用于选择并应用样式到HTML...这些CSS选择器的掌握,能帮助开发者更高效、精确地定位和样式化网页元素。理解它们的特性和适用场景,有助于编写出更优化、可维护的CSS代码。

    它使用仿CSS选择器的语法来生成代码,大大提高了HTML/CSS代码编写的速度

    标题中的“它使用仿CSS选择器的语法来生成代码”指的是Emmet,这是一个非常流行的Web开发工具,尤其在HTML和CSS编码中广泛使用。Emmet通过简化和加速编写复杂的HTML结构和CSS规则来提高开发效率。它允许开发者使用...

    最好用的Css编辑器

    1. **代码提示和自动完成**:TopStyle Portable可能会提供强大的代码补全功能,能够自动完成CSS选择器、属性和值,减少输入错误并提升编写速度。 2. **实时预览**:编辑器可能集成了实时预览功能,允许开发者在编写...

    高效编写CSS代码的建议汇总

    在编写CSS时,如果遇到多个选择器具有相似的属性和值,应该考虑将这些相似部分抽取出来,使用类组合的方式统一定义。这样做不仅可以减少代码量,还能提高代码的可维护性。例如,如果有多个类需要相同的定位属性,...

    CSS选择器分组.pdf

    通过理解并熟练运用CSS选择器分组、声明分组和多重嵌套声明,开发者可以更高效、更精确地控制网页元素的样式,从而实现更复杂的布局和视觉效果。在编写CSS时,应根据需要灵活运用这些技巧,以保持代码的清晰度和可...

Global site tag (gtag.js) - Google Analytics