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

所属分类: 网页制作 / CSS 阅读数: 2017
收藏 0 赞 0 分享

CSS规范并没有明确浏览器如何去实现样式系统,仅仅是说明了它们必须这样做。有鉴于此,不同的样式系统引擎可能会拥有完全不同的表现和行为,特别是 Gecko 与 WebKit, 这两个引擎都是开源项目,实现了类似的算法,具有极其相近的优缺点。因此下面介绍的小技巧对于真实世界的 Web 文档将会十分有用。

第一部分内容综合讨论了常见的样式系统是如何分类规则的。接下来的部分包含了书写规则的指南,它利用了前面讨论的样式系统的优点。

样式系统如何拆分规则

样式系统将规则拆分成四个主要类别:

1.ID 规则
2.Class 规则
3.标签规则
4.通用规则
理解这些分类是十分关键的,因为它们是构建规则匹配块的基础。

我在下面的段落中使用术语 关键选择器(key selector)。选择器的最后面的部分即为关键选择器(即用来匹配目标元素的那部分,而不是该元素的祖先元素)。

例如,在下面规则中…

CSS Code复制内容到剪贴板
  1. a img,    
  2. div > p,    
  3. h1 + [title] {   
  4.   …   
  5. }  

关键选择器为 img、 p 和 title.

ID 规则

这第一个类别包含了那些将 ID 选择器作为关键选择器的规则。

示例

CSS Code复制内容到剪贴板
  1. button#backButton {…} /* This is an ID-categorized rule */  
  2. #urlBar[type="autocomplete"] {…} /* This is an ID-categorized rule */  
  3. treeitem > treerow > treecell#myCell:active {…} /* This is an ID-categorized rule */  

Class 规则

如果一个规则将一个 class 明确作为它的关键选择器,那么它就属于该类别。

示例

CSS Code复制内容到剪贴板
  1. button.toolbarButton {…} /* A class-based rule */  
  2. .fancyText {…} /* A class-based rule */  
  3. menuitem > .menu-left[checked="true"] {…} /* A class-based rule */  

标签规则

如果既没有 class 也没有 ID 来明确作为关键选择器,那么接下来的候选者就是 标签 类别。 如果一条规则将一个标签作为它的关键选择器,那么这条规则就属于该类别。

示例

CSS Code复制内容到剪贴板
  1. td {…} /* A tag-based rule */  
  2. treeitem > treerow {…} /* A tag-based rule */  
  3. input[type="checkbox"] {…} /* A tag-based rule */  

通用规则

不属于上面那些类别的规则都属于这个类别。

示例

CSS Code复制内容到剪贴板
  1. [hidden="true"] {…} /* A universal rule */     
  2. * {…}  /* A universal rule */  
  3. tree > [collapsed="true"] {…} /* A universal rule */  

样式系统如何匹配规则

样式系统从关键选择器开始匹配规则,然后左移(查找规则选择器的任何祖先元素)。只要选择器的子树(substree)一直在检查,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该条规则。

规则过滤是你需要学习的最基础的概念。分类存在的意义就是过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。

这就是能够极大提高性能的关键。对于一个给定的元素,需要匹配的规则越少,样式的解析就会越快。

举个例子,如果一个元素拥有一个 ID,那么只有匹配该 ID 的 ID 规则才会被选中。同理,只有当 Class 规则中的 class 出现在元素上时该规则才被检查。只有当标签规则的标签匹配时该规则才被检查。通用规则始终都会检查。

高效 CSS 指南

避免通用规则

请确保规则不以通用类型选择器作为结束!

不要用标签名或 classes 来限定 ID 规则

如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签名。因为 ID 是唯一的,增加标签只会没必要地减缓匹配过程。


CSS Code复制内容到剪贴板
  1. button#backButton {…}  


CSS Code复制内容到剪贴板
  1. .menu-left#newMenuIcon {…}  


CSS Code复制内容到剪贴板
  1. #backButton {…}  


CSS Code复制内容到剪贴板
  1. #newMenuIcon {…}  

例外:在不同的场景下,要动态改变元素的class,从而应用不同的样式,这是可取的。但是这个相同的class是与其他元素所共享的。
不要用标签名限定 class 规则

前面那节内容在这里同样适用。虽然在同一页面能够多次使用 class,但它仍然比标签名更独特。

按照惯例,你可以将标签名包含在 class 名里。但是,这会有损灵活性;如果设计更改以至于要变更标签,这条class 名也必须跟着变动。(最好的办法是选择严格语义化的名字,毕竟分离样式表的一个目标就是为了灵活性。)


CSS Code复制内容到剪贴板
  1. treecell.indented {…}  


CSS Code复制内容到剪贴板
  1. .treecell-indented {…}  


CSS Code复制内容到剪贴板
  1. .hierarchy-deep {…}  

尽量使用最具体的类别

解析速度变慢的罪魁祸首就是标签类别中有过多的规则。通过增加 class 到元素上,我们就可以进一步的将这些规则划分到 Class 类别中,这将减少用于匹配标签的时间。


CSS Code复制内容到剪贴板
  1. treeitem[mailfolder="true"] > treerow > treecell {…}  


CSS Code复制内容到剪贴板
  1. .treecell-mailfolder {…}  

避免后代选择器

后代选择器是 CSS 中性能耗用最大的选择器。 它是性能开销相当大的——特别是当选择器在标签或通用类别中。

通常我们需要的是 子选择器。比如说,当性能十分差的时候,Firefox 的用户界面CSS 将毫无理由的禁止掉后代选择器。你也应该在网页中这么做。


CSS Code复制内容到剪贴板
  1. treehead treerow treecell {…}  

略好,但还是差(查看下一条指南)

CSS Code复制内容到剪贴板
  1. treehead > treerow > treecell {…}  

标签分类的规则不要包含子选择器

标签类别的规则中避免使用子选择器。否则的话,在该元素出现的所有地方,匹配时间都将极大延长(特别是当规则很可能会被匹配)。


CSS Code复制内容到剪贴板
  1. treehead > treerow > treecell {…}  


CSS Code复制内容到剪贴板
  1. .treecell-header {…}  

在使用子选择器的地方想想为什么

当使用子选择器时要十分谨慎。能免则免。

特别来说,子选择器常常用于 RDF 树与菜单:


CSS Code复制内容到剪贴板
  1. treeitem[IsImapServer="true"] > treerow > .tree-folderpane-icon {…}  

要记住,模板中的 REF 特性可以重复出现!好好利用这一优点。在子 XUL 元素上重复使用 RDF 属性,这样可以基于该属性来修改元素。

GOOD

CSS Code复制内容到剪贴板
  1. .tree-folderpane-icon[IsImapServer="true"] {…}  

依赖继承

了解哪些属性能够继承,然后允许它们这样做!

例如,XUL组件会明确的设置,使得父级元素的列表样式图像或字体规则衍生到匿名内容。因而没有必要去在匿名内容上直接应用规则浪费时间。


CSS Code复制内容到剪贴板
  1. #bookmarkMenuItem > .menu-left { list-style-imageurl(blah) }  


CSS Code复制内容到剪贴板
  1. #bookmarkMenuItem { list-style-imageurl(blah) }  

在以上示例中,要为匿名内容应用样式(不利用 list-style-image 的继承特性),将会产生Class分类中的规则,当这条规则本应该止于ID分类——所有分类中最确切的分类。

谨记: 所有元素都有同一种class,尤其是匿名内容!

上面示例中的“差”规则强制每个菜单的图标都要在包含书签的菜单项内进行测试。因为这里有很多菜单,这将是极其耗费的。相反,这条“好”规则将测试限制在书签菜单(外围容器,非单独项)内。

使用 -moz-image-region!

如果你正在开发针对Mozilla的代码:将一系列图像放置在一个单独的文件中,然后使用 -moz-image-region 进行选择,这比将他们分别放在自身的文件中来选择要表现得更加良好。

使用局部样式表

如果你能够明确将样式表作为XBL源,这些样式仅仅应用在被绑定的元素和其中的匿名内容上。这会减小通用规则和子元素选择器带来的负面影响,因为他们考虑的元素会更少。

如非必要则避免特定浏览器的渲染特征

总有有一些针对特定浏览器的或者实验性的标签和CSS属性,他们以前缀的形式来区分能够起作用的浏览器,例如 -webkit、-moz、 -ms、-o 等等。一旦某个标签或属性被标准化,这些前缀属性就会被移除。举个例子,在 border-radius 被标准化和被所有主流浏览器实现之前,你必须使用 -webkit-border-radius 和 -moz-border-radius 等属性。

对特定渲染的前缀和标签及属性的标准化的变化保持意识,并且在任何可行的时间都要去避免使用任何特定渲染的特性。

更多精彩内容其他人还在看

Opera中国的WEB标准课程

网页制作Webjx文章简介:在这篇文章里,我要向大家介绍我和其他很多人花费数月时间开发的一个课程——Web标准课程,该课程旨在向大家提供Web设计和开发的坚实基础,无论读者是谁,此教程完全免费、可访问,并且不需要预备知识。当然,我主要还
收藏 0 赞 0 分享

CSS样式表渐进增强的基本概念

网页制作Webjx文章简介:如果你挠着头想弄清楚优雅降级和渐进增强的区别,我告诉你,这是视角问题。优雅降级和渐进增强都考虑网站在各种设备的各种浏览器上如何良好运转。两者区别的关键在于它们各自关注的焦点,以及这种关注对工作流程的影响
收藏 0 赞 0 分享

简单介绍Web Developer插件制作网页

网页制作Webjx文章简介:Firefox浏览器是一个良好支持W3C标准的开放源代码的浏览器,拥有Linux/Windows/Mac版本。因为Firefox浏览器良好支持W3C标准,所以使用Firefox来调试网页是非常好的。 Firefox浏览器是
收藏 0 赞 0 分享

CSS布局带来的巨大影响:CSS display属性值

网页制作Webjx文章简介:网页元素应用上那些与表格相关的display属性值后,能够模仿出与表格相同的特性。我将会在该文中给大家演示这种方法给CSS布局带来的巨大影响。 应原书编辑要求,先在文章顶部给出链接:《Everything You
收藏 0 赞 0 分享

用div css模拟表格对角线

这只是探讨一种CSS模拟表格对角线的用法,实际在工作中可能觉得这样做有点小题大作,这不是本主题讨论的重点。如果对此深以为然的朋友,请一笑过之 首先声明: 这只是探讨一种CSS模拟表格对角线的
收藏 0 赞 0 分享

IE Firefox在css中的差别 (部分)

1、单位问题 问题:任何距离的数值ie可以不加单位,ff必须要求写单位(0除外) 解决:写全单位如padding:0px; 2、水平居中 问题:div里的内容,ie默认为center,而ff默认left 解决:mairgin:0px auto; 3、高度问题
收藏 0 赞 0 分享

不用js可以实现信息提示效果

[code] <style> body { font:verdena; font-size:14px; color:#000 } h1{ font:verdena; font-size:22px; color:#000 } h2{ font:verdena;
收藏 0 赞 0 分享

CSS解决未知高度的垂直水平居中自适应问题

今天有人问起,晚上试着写出来,供参考; 以下代码兼容主流浏览器IE6、IE7、Firefox、Opera。 从最简单的开始………… 一、如何让一个DIV水平居中? 这个简单不作过多说明! [code] <st
收藏 0 赞 0 分享

CSS cursor 属性 -- 鼠标指针样式效果

取值: [ [<uri> ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-resize | n-resize | se-resize | sw-resize |
收藏 0 赞 0 分享

css 简单区别ie6,ie7,firefox的写法

同一样式里可以这样 [code] margin:17px; FF +margin:17px; IE6 IE7 _margin:17px; IE6 [/code] 按这个顺序,刚好区分开三个浏览器
收藏 0 赞 0 分享
查看更多