【高性能前端 2】高性能 CSS
In 未分类 on 2012年10月10日 by view: 23,560
27

避免使用 @import

有两种方式加载样式文件,一种是 link 元素,另一种是 CSS 2.1 加入 @import。而在外部的 CSS 文件中使用 @import 会使得页面在加载时增加额外的延迟。虽然规则允许在样式中调用 @import 来导入其它的 CSS,但浏览器不能并行下载样式,就会导致页面增添了额外的往返耗时。比如,第一个 CSS 文件 first.css 包含了以下内容:@import url("second.css")。那么浏览器就必须先把 first.css 下载、解析和执行后,才发现及处理第二个文件 second.css。简单的解决方法是使用<link> 标记来替代 @import,比如下面的写法就能够并行下载 CSS 文件,从而加快页面加载速度:

需要注意的是一个页面中的 CSS 文件不宜过多,否则应该简化及合并外部的 CSS 文件以节省往返请求时间 (RTT) 提升页面加载速度。

避免 AlphaImageLoader 滤镜

IE 独有属性 AlphaImageLoader 用于修正 7.0 以下版本中显示 PNG 图片的半透明效果。这个滤镜的问题在于浏览器加载图片时它会终止内容的呈现并且冻结浏览器。在每一个元素(不仅仅是图片)它都会运算一次,增加了内存开支,因此它的问题是多方面的。完全避免使用 AlphaImageLoader 的最好方法就是使用 PNG8 格式来代替,这种格式能在 IE 中很好地工作。如果你确实需要使用 AlphaImageLoader,请使用下划线_filter 又使之对 IE7 以上版本的用户无效。

避免 CSS 表达式

CSS 表达式是动态设置 CSS 属性的强大(但危险)方法。Internet Explorer 从第 5 个版本开始支持 CSS 表达式。下面的例子中,使用 CSS 表达式可以实现隔一个小时切换一次背景颜色:

如上所示,expression 中使用了 JavaScript 表达式。CSS 属性根据 JavaScript 表达式的计算结果来设置。expression 方法在其它浏览器中不起作用,因此在跨浏览器的设计中单独针对 Internet Explorer 设置时会比较有用。

表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给 CSS 表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到 10000 次以上的计算量。一个减少 CSS 表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替 CSS 表达式。如果样式属性必须在页面周期内动态地改变,使用事件句柄来代替 CSS 表达式是一个可行办法。如果必须使用 CSS 表达式,一定要记住它们要计算成千上万次并且可能会对你页面的性能产生影响。

避免通配选择器

CSS 选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免需要消耗更多匹配时间的选择器。而在这之前我们需要了解 CSS 选择器匹配的机制,如例子的子选择器规则:

我们中的大多数人都是从左到右的阅读习惯,可能也会习惯性的设定浏览器也是从左到右的方式进行匹配规则,因为会推测这条规则的开销并不高。我们这样假象浏览器会像这样的方式工作:找到唯一的 id 为 header 为的元素,然后把这个样式规则应用到直系子元素中的 a 元素上。我们知道文档中只有一个 id 为 header 的元素,并且它只有几个 a 类型的子节点,所以这个 CSS 选择器应该相当高效。

事实上,却恰好相反,CSS 选择器是从右到左进行规则匹配。了解这个机制后,例子中看似高效的选择器在实际中的匹配开销是很高的,浏览器必须遍历页面中所有的 a 元素并且确定其父元素的 id 是否为 header。

如果把例子的子选择器改为后代选择器则会开销更多,在遍历页面中所有 a 元素后还需向其上级遍历直到根节点。

理解了 CSS 选择器从右到左匹配的机制后,可以理解选择器中最右边的规则往往决定了浏览器继续左移匹配的工作量,我们把最右边选择规则称之为关键选择器。

通配选择器使用 * 符合表示,可匹配文档中的每一个元素。如下例规则将所有元素的字体大小设置为 20px:

通配选择器作用于所有的元素,如规则最右边为通配符:

浏览器匹配文档中所有的元素后分别向上逐级匹配 class 为 selected 的元素,直到文档的根节点,因此其匹配开销是非常大的,通常比开销最小的 ID 选择器高出 1~3 个数量级,所以应避免使用关键选择器是通配选择器的规则。

避免单规则的属性选择器

属性选择器根据元素的属性是否存在或其属性值进行匹配,如下例规则会把 herf 属性值等于”#index” 的链接元素设置为红色:

但其匹配开销是非常大的,浏览器先匹配所有的元素,检查其是否有 href 属性并且 herf 属性值等于”#index”, 然后分别向上逐级匹配 class 为 selected 的元素,直到文档的根节点。所以应避免使用关键选择器是单规则属性选择器的规则。

避免类正则的属性选择器

CSS3 添加了复杂的属性选择器,可以通过类正则表达式的方式对元素的属性值进行匹配。当然这些类型的选择器定是会影响性能的,正则表达式匹配会比基于类别的匹配会慢很多。大部分情况下我们应尽量避免使用 *=, |=, ^=, $=, 和 ~=语法的属性选择器。

移除无匹配的样式

移除无匹配的样式,有两个好处:

第一,删除无用的样式后可以缩减样式文件的体积,加快资源下载速度;

第二,对于浏览器而言,所有的样式规则的都会被解析后索引起来,即使是当前页面无匹配的规则。移除无匹配的规则,减少索引项,加快浏览器查找速度;

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2012/10/high-performance-css/

  1. 前端学习需要的资源网站集合 | 亿浪博客 2017 年 2 月 7 日

    […]               –【高性能前端 1】高性能 HTML                –【高性能前端 2】高性能 CSS                – 由 12306 谈谈网站前端性能和后端性能优化              […]

  2. Awesome! – IDEAL 2017 年 1 月 30 日

    […] 高性能 CSS […]

  3. 前端资源教程 – w3cmart 2016 年 11 月 3 日

    […]【高性能前端 2】高性能 CSS […]

  4. {转}最全前端资源汇集 – 前端笔记 2016 年 10 月 24 日

    […] http://www.alloyteam.com/2012/10/high-performance-html【高性能前端 2】高性能 CSS http://www.alloyteam.com/2012/10/high-performance-css 由 12306 谈谈网站前端性能和后端性能优化 http://coolshell.cn/articles/6470.html […]

发表评论