提高 web 应用性能之 CSS 性能调优

CSS 性能调优

CSS 代码的分析与渲染都是由浏览器来完成的,所以,了解浏览器的 CSS 工作机制对我们的优化有至关重要的作用。这篇文章我们主要从如下几个方面入手来介绍一下 CSS 的性能优化:

  1. Style 标签的相关调优
  2. 特殊的 CSS 样式使用方式
  3. CSS 缩写
  4. CSS 的声明
  5. CSS 选择器

把 Stylesheets 放在 HTML 页面头部:

浏 览器在所有的 stylesheets 加载完成之后,才会开始渲染整个页面,@import 就相当于是把 <link> 标签放在页面的底部,所以从优化性能的角度看,应该尽量避免使用 @import 命令

避免使用 CSS Expressions:

 Background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" )

Expression 只有 IE 支持,而且他的执行比大多数人想象的要频繁的多。不仅页面渲染和改变大小 (resize) 时会执行,页面滚动 (scroll) 时也会执行,甚至连鼠标在页面上滑动时都会执行。在 expression 里面加上一个计数器就会知道,expression 的执行上相当频繁的。鼠标的滚动很容易就会使 expression 的执行次数超过 10000。

避免使用 Filter:

IE 特有的 AlphaImageLoader filter 是为了解决 IE6 及以前版本不支持半透明的 PNG 图片而存在的。但是浏览器在下载 filter 里面的图片时会“冻结”浏览器,停止渲染页面。同时 filter 也会增大内存消耗。最不能忍受的是 filter 样式在每个页面元素(使用到该 filter 样式)渲染时都会被浏览器分析一次,而不是像一般的背景图片渲染模式:使用过该背景图片的所有元素都是被浏览器一次性渲染的。

针对这种情况,最好的解决办法就是使用 PNG8。

CSS 缩写:

缩写
 #000000     ------>>     #000 
 #336699     ------>>     #369
 Margin-top: 2px; 
 Margin-right: 5px; 
 Margin-bottom: 2em; 
 Margin-left: 15px;     ----->>     Margin: 2px 5px 2em 15px; 

 Border-width: 1px; 
 Border-style: solid; 
 Border-color: #000     ----->>     border: 1px solid #000 

 Font-style: italic; 
 Font-variant: small-caps; 
 Font-weight: bold; 
 Font-size: 1em; 
 Line-height: 140%; 
 Font-family: sans-serif;  ----->>  font: italic small-caps bold 1em 140% sans-serief 

 Background-color: #f00; 
 Background-image: url(background.gif); 
 Background-repeat: no-repeat; 
 Background-attachment: fixed; 
 Background-position: 0 0; 
  ----->>background: #f00 url(background.gif) no-repeat fixed 0 0 

 list-style-type: square; 
 list-style-position: inside; 
 List-style-image: url(image.gif)  ----->> list-style: square inside url(image.gif)

Multiple Declarations

.Class1{position: absolute; left: 20px; top: 30px;} 
.Class2{position: absolute; left: 20px; top: 30px;} 
.Class3{position: absolute; left: 20px; top: 30px;} 
.Class4{position: absolute; left: 20px; top: 30px;} 
.Class5{position: absolute; left: 20px; top: 30px;} 
.Class6{position: absolute; left: 20px; top: 30px;} 

 -------------------->>>>>>> 

 .class1 .class2 .class3 .class4 .class5 .class6{ 
 Position: absolute; left: 20px; top: 20px; 
 }

CSS 选择器 (CSS Selectors)

先来看看下面这个例子:

清单 5. Child selector
 #toc > li {font-weight: bold}

按照我们惯常的理解,编译器应该是先查找 id 为“toc”的节点,然后在他的所有直接子节点中查找类型(tag)为“li”的节点,将“font-weight”属性应用到这些节点上。

但是,不幸的是,恰恰相反,浏览器是“从右往左”来分析 class 的,它的匹配规则是从右向左来进行匹配的。这里,浏览器首先会查找页面上所有的“li”节点,然后再去做进一步的判断:如果它的父节点的 id 为“toc”,则匹配成功。

由此可知,CSS 选择器的匹配远比我们想象的要慢的多,CSS 的性能问题不容忽视。

清单 6. Descendant selector
 #toc  li {font-weight: bold}

这个效率比之前的“child selector”效率更慢,而且要慢很多。浏览器先便利所有的“li”节点,然后步步上溯其父节点,直到 DOM 结构的根节点(document),如果有某个节点的 id 为“toc”,则匹配成功,否则继续查找下一个“li”节点。

清单 7. 尽量避免 universal rules
 [hidden="true"] { ... } /* A universal rule */

这里的匹配规则很明显:查找页面上的所有节点,如果有节点存在“hidden”属性,并且其属性值为“true”,则匹配成功。这是最耗时耗力的匹配,页面上的所有节点都需要进行匹配运算,这种规则应尽量避免。

清单 8. Id-categorized 规则与 tag name 或 class 规则并行
 button#goButton {...};----->>#goButton 
 .fundation#testIcon {...};----->>#testIcon

这里,按照我们常规的理解,箭头左边的写法似乎是应该更快的,因为它的限制更多。其实不然,id 是全局唯一的,在匹配 CSS 选择器时浏览器定位到 id 是最快的,如果伴随有其他的非 id 的 selector,反而会影响匹配的效率。

清单 9. 关于 class-categorized 规则
 button.indented {...}----->>.button-indented {...}

程 序员们经常会给某个 Class 前面加上标签名称(Tag Name),以更精确且快速的定位该节点,但是这样往往效率更差。和清单 8 中的原理一样,页面上的 class 在全局范围内来讲应该是唯一的,用唯一的 Class 名称来定位一个节点往往比组合定位更加快捷。事实上,这种做法也可以避免由于开发修改页面元素的类型(Tag)而导致的样式失效的情况,做到样式与元素的 分离,两者独立维护。

清单 10. 尽量减少规则数量
 Span[mailfolder="true"] > table > tr > td.columnClass {...} 

 ------------------->>>>>>> 

 .span-mailfolder-tbl-tdCol {...}

规则越多,匹配越慢,上面一种规则需要进行 6 项匹配,先找“columnClass”,再找“td”,然后是“tr”,“table”,最后是符合“mailfolder”为“true”的 span,这种效率是非常慢的。如果用一个比较特殊的 class 替代(span-mailfolder-tbl-tdCol),效率会快上好几倍。

清单 11. 尽量避免使用 descendant selector
 treehead treerow treecell {...} ----->> treehead > treerow > treecell {...}

Descendant 选择器是耗时相对高的选择器,通常来讲,它在 CSS 里的使用应该是尽量避免的,如果能用 child 选择器替代就应该尽量这样去做。

清单 12. 利用 CSS 的继承机制
 Color 
 Font 
 Letter-spacing 
 Line-height 
 List-style 
 Text-align 
 Text-indent 
 Text-transform 
 White-space 
 Word-spacing 



 #bookmark  > .menu-left {list-style-image: url(blah)} 

 ------------>>>>>>>> 

 #bookmark  {list-style-image: url(blah)}

很多 CSS 属性可以继承,如:color, font 等 ...,并且子节点无需更改该样式,则无需再作相关设定

结束语

这 篇文章介绍了 Web 开发中关于 CSS 性能方面需要注意的一些小细节,从 CSS 本身着手,介绍了编写 CSS 代码中需要避免的一些写法,比如 CSS Expression 的弊端,CSS 缩写以及 CSS 选择器的注意事项等等,也分享了一些比较推荐的做法。我们可以在开发过程中尽量注意一下这些小细节,以尽可能多的提高我们 Web 应用的性能。

参考资料

学习

  • CSS wiki:http://en.wikipedia.org/wiki/CSS一个共享 CSS 开发知识的网站,提供很多 CSS 的实例和解释。
  • CSS W3C 标准:http://www.w3.org/TR/CSS21/提供了很多 CSS 的标准和使用指南,有很多经典实例。
  • 提高 web 应用性能之 JavaScript 性能调优” (developerWorks,2011 年 7 月):JavaScript 是一个比较完善的前端开发语言,在现今的 web 开发中应用非常广泛,尤其是对 Web 2.0 的应用。随着 Web 2.0 越来越流行的今天,我们会发现:在我们的 web 应用项目中,会有大量的 JavaScript 代码,并且以后会越来越多。JavaScript 作为一个解释执行的语言,以及它的单线程机制,决定了性能问题是 JavaScript 的软肋,也是 web 软件工程师们在写 JavaScript 需要高度重视的一个问题,尤其是针对 Web 2.0 的应用。绝大多数 web 软件工程师都或多或少的遇到过所开发的 Web 2.0 应用的性能欠佳的问题,其主要原因就是 JavaScript 性能不足,浏览器负荷过重。但是,解决这种解释执行并且单线程运作语言的性能问题也并非易事。这篇文章会着重介绍一些关于开发中 JavaScript 性能调优的技巧和最佳实践,同样也会涉及到关于 JavaScript 操作 DOM 节点的性能调优的一些方法 .
  • 使用 Dojo 的 Ajax 应用开发进阶教程,第 3 部分:深入理解 CSS” (developerWorks,2010 年 9 月):CSS 作为 HTML 页面中控制展现的标准技术,已经为广大 Web 开发人员所熟悉。虽然 CSS 本身的语法比较简单,但是在复杂的 Web 应用中编写和管理 CSS 并非一件容易的事情。本文讨论了 CSS 规范中比较复杂和容易出错的部分,接着讨论了浏览器的兼容性和如何开发出可维护的 CSS,最后介绍了相关的框架和工具以及 Dojo 提供的 API 支持。
  • developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
  • developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
  • developerWorks Web 2.0 资源中心,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过 Web 2.0 新手入门 栏目,迅速了解 Web 2.0 的相关概念。
  • 查看 HTML5 专题,了解更多和 HTML5 相关的知识和动向。

讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。