`
mywebcode
  • 浏览: 1002887 次
文章分类
社区版块
存档分类
最新评论

编写高效的CSS选择器

 
阅读更多

高效的CSS已经不是一个新话题,也不是一个我非得重拾的话题,但是,它却是自我在SKY工作以后,真正感兴趣并始终关注的一个话题。

很多人或者忘记了,或者仅仅是没有意识到,CSS可以是高效的也可能导致低能。然而,我们可以不考虑当你自认为会的太少而使用了低效的CSS这种情况。

这些规则只真正用在性能要求很高的网站上,这些网站对速度要求很高,任何一个页面可能含有成百上千个DOM元素。但是实践出真理,不管你是在打造下一个facebook 还是在开发一个本地的展示网页,多学点总是好的....

CSS 选择器

CSS 选择器对我们大多数人来说并不新鲜,较基础的选择器分别是类型(如 div),ID(如#header)和类(如.tweet)。

较不寻常的包括基础的伪类(如:hover)和更复杂的CSS3以及 '正则'(‘regex’)选择器,比如:first-childor[class^="grid-"]。

选择器具有固有效率,引用Steve Souders的话来说,较有效到较不有效的CSS选择器的顺序是这样的:

  1. ID,如#header
  2. Class, 如.promo
  3. Type, 如div
  4. Adjacent sibling, 如h2 + p
  5. Child, 如li > ul
  6. Descendant,如ul a
  7. Universal,即*
  8. Attribute, 如[type="text"]
  9. 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的网站与书也不过分。对你需要的延伸阅读来说,那足够了。这伙计知道的很多!

分享到:
评论

相关推荐

    高效的CSS选择器编写指南

    高效的CSS已经不是一个新的话题了,也不是我一个非得重拾的话题,但它却是我在Sky公司工作之时,所感兴趣的,关注已久的话题。...对我们大多数人来说,CSS选择器并不陌生。最基本的选择器是元素选择器(比如div),ID选择

    css-selector-generator-benchmark:用于生成CSS选择器的各种JavaScript库的基准

    CSS选择器生成器基准 这是为各种JavaScript库创建基准以生成CSS选择器的尝试。 它受到@dandv的启发。 用法 npm install npm test index.html应该在浏览器选项卡中打开,并带有进一步的说明。 结果 @antonmedv NPM包...

    CSS编写时的高性能以及高维护性代码优化建议总结

    一、使用高效css选择器 简单来说,能被浏览器快速解析和匹配的css选择器,就是高效的选择器。 首先要知道浏览器如何解析css 举个例子: CSS Code复制内容到剪贴板 .nav ul.list li div{}  我们常见的思维是,...

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

    主要介绍了高效编写CSS代码的建议汇总,包括选择器和伪元素等在编程时使用的建议,强烈推荐!需要的朋友可以参考下

    xml-selector:使用 CSS 样式选择器处理 XML 的类似 jQuery 的界面

    它提供了部分 DOM 支持和类似 jQuery 的界面,用于使用 CSS 样式选择器遍历 XML 文档。 请注意,从 0.3 版开始,XML Selector 使用它自己的基于的 DOM 实现。 这与之前的非标准文档界面不同。 XML Selector 当前...

    【前端素材】模板-多种实用城市选择器.zip

    CSS 预处理器:使用像 Sass、Less 等 CSS 预处理器可以简化 CSS 编写过程,提高样式代码的可维护性,进而对动画效果的实现有所帮助。 综上所述,前端动画素材的技术实现方式多种多样,开发者可以根据项目需求和个人...

    CSS代码编写的一些性能优化技巧总结

    主要介绍了CSS代码编写方面的一些优化技巧总结,谈到了包括避免通用规则和后代选择器等方面来使代码更加高效,需要的朋友可以参考下

    Typora:简洁高效的Markdown文本编辑器.zip

    typora.强大的Markdown支持 尽管Typora提供了直观的图形界面,但它并没有忽视Markdown语法的支持。...此外,Typora还支持自定义CSS样式,高级用户可以通过自定义样式来调整编辑器的外观和文档的排版。

    PythonSpider-master ,Python各网站爬虫脚本

    Python是一种非常流行的编程语言,也被广泛用于编写网络爬虫。Python提供了许多强大的库和框架,使得开发和执行爬虫任务变得简单和...你可以使用CSS选择器或XPath来定位元素,并使用相应的方法获取文本、属性或链接等信

    移动应用开发的概要设计与介绍

    移动应用开发是当前技术领域的...开发者可以利用各种设计资源和工具来创建应用的UI/UX,如设计模板、图标库、颜色选择器等。设计工具如Sketch、Adobe XD等提供了丰富的功能和素材,帮助开发者设计出吸引人的用户界面

    massCode-1.1.0-mac.zip 针对开发人员的代码段管理器

    该编辑器提供IntelliSense,TypeScript,JavaScript,CSS,LESS,SCSS,JSON,HTML的验证。我们还向代码格式化程序添加了超级高效的Emmet和Prettier。纸盘助手massCode助手位于纸盘中,使您能够始终使用搜索快速访问...

    Sass与Compass实战

    本书共分为10章,旨在完整...本书介绍了Sass如何通过选择器嵌套和变量来帮助避免重复,以及通过继承和混合器等特性更加高效地重用通用样式,减少重复编写工作。学完本书后,你一定能对Sass和Compass有一个全面的理解。

    Sublime Text 2.0.1 正式版

    Sublime Text 2 被称作Windows下的TextMate,而根据其官网介绍,Sublime Text的特点如下:拥有高效、没有干扰的界面,在编辑方面的多选、宏、代码片段等功能,以及很有特色的Minimap。 自从 Sublime Text 2.0 正式...

    JavaScript实战

    5.4.1 基本选择器 130 5.4.2 高级选择器 133 5.4.3 jQuery过滤器 135 5.4.4 理解jQuery选择 136 5.5 向页面添加内容 138 替换和删除选择 141 5.6 设置和读取标签属性 142 5.6.1 类 142 5.6.2 读取和改变CSS属性 143 ...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    Chrome Frame 会把最新版的Chrome Webkit 内核和JavaScript 引擎注入到IE中, IE浏览器将获得Chrome的性能和功能 目录 摘要 I ABSTRACT II 专业名词清单 III 第一章 绪论 1 1.1 研究背景与意义 1 1.2国内外相关...

    JAVA毕业设计之学生选课系统(springboot+mysql)完整源码.zip

    本系统采用了分层架构设计,主要包括以下几个部分:前端页面:使用HTML、CSS和JavaScript编写,实现了用户界面的展示和交互功能。控制器层:使用Spring MVC框架实现,负责处理用户请求,调用业务逻辑层的方法,并将...

    基于zigbee和stm32的智能家居系统.zip

    安全与保护机制:如加密加速器、安全单元、内存保护单元(MPU)、看门狗定时器、时钟安全系统(CSS)等,保障系统安全稳定运行。 开发环境与生态系统 STM32拥有强大的软件支持和生态系统,简化开发流程并加速产品...

    codework:使用解决方案进行编程的任务清单

    高效SQL选择示例 C ++ 2016.测试素数 2016.使用内存的库 2016.返回链接 JavaScript 2017.面试与准备 2016.旅行者卡分类器 2016.用于DOM元素CSS类的JS框架 2016.制定“动员”项目的演讲时间表 2016年。编写一个库...

Global site tag (gtag.js) - Google Analytics