概要:帮助你实现样式表的最佳性能
本章内容:
● 样式表拼接
● 样式表和资源压缩
● 减少和并行图片请求的策略
● 选择器性能和优化策略
1. 测量客户端性能
性能优化的起点和终点都是测量。在第一次改变性能位置之前,你需要知道自己究竟在什么位置。
下面是一些工具:
● YSlow:http://developer.yahoo.com/yslow/。
● Google PageSpeed:http://developers.google.com/pagespeed/。
● WebPagetest:http://www.webpagetest.org/
1.1 回避带有服务器端@import的HTTP请求
正如你在第3章中看到的,@import指令是一个非常有用的工具,它能够将大型的样式表组织为较小的部分,以便轻松地查找样式。在CSS的一个样式表中导入许多其他的样式表并不鲜见:
@import url("blog.css") ; @import url("forum.css") ; @import url("article.css") ; @import url("header.css") ; @import url("footer.css") ;
这样的写法降低了第一个页面的速度,因为它需要数个HTTP请求以下载所需要的多个样式表。CSS的最佳实践之处,要讲你的样式表连接成少数几个样式表。这就是Sass提供服务器端导入的原因:
@import“blog”,“forum”,“article”,“header”,“footer”;
这将提高第一个页面的载入速度,因为所有的样式表只需要一次请求就能下载完成。许多网站采取的策略是将CSS文件组织为三个层级:
● 核心样式表:几乎每个页面都需要的普通样式。
● 部分样式表:应用或者网站的某个大型部分需要的普通样式。
● 单页样式表:只有某个单独页面需要的样式,经常用于销售页面这样设计复杂而独特的页面。
2.用压缩减少传输时间
有个简单的方法能让你的网站变得更快:缩小在互联网中传送内容的大小。
2.1 gzip压缩
大多数现代浏览器会连同请求发送一个请求首部Accept-Encoding:gzip,只要响应中含有一个包含Content-Encoding:gzip的首部,就能被压缩。通常,优化前端性能的最佳方式是尽可能缩小资源的网络复写。对于所有关注客户端性能的网站来说,使用gzip压缩文本资源并优化网络图片都是必行之事。
预压缩样式表并根据请求首部提供不同的文件也是一种可行办法。设置方法应该依据服务器来具体分析。但是如果你需要进行这样的设置,Compass提供了一种简单的方式来自动生成压缩样式表。你可以在Compass中注册一个回调函数,每当保存一个新的样式表,它都会运行。将下面的代码添加到你的Compass配置文件中即可:
on_stylesheet_save do |filename| # run the gzip tool on the file # generates a file of the same name # plus a .gz at the end. ‘gzip -f #{file}‘ end
2.2 图片压缩
关于图片,你首先需要了解的是,大多数图片格式拥有内建的压缩方式。基本的法则就是,针对不同的图片,你应该使用能够达到最大压缩程度的不同图片格式。也就是说,你一般应该使用下面几种格式:
● GIF格式用于颜色数量少的小文件;
● JPG格式用于在图片质量设置为最低值时不会引起图片质量明显下降的摄影图片;
● PNG格式用于其他图片。
PNG是一种能够处理多种图片类型的复杂格式。确保移除其中的alpha层,否则会得到透明效果。
3. 用资源托管提高页面加载速度
HTTP/1.1标准中指出,Web浏览器应该限制每次页面请求中单个域的同步下载数量,从而达到最佳效果。但是在许多服务器上运行的负载均衡网站可以很好地处理这种突发流量,因此你需要对浏览器耍一点小把戏来解决这一问题。一种普遍的策略是注册多个域(或者子域),并将它们解析到同一个地方。
除了具有并行的好处,设置资源托管来使用一个无cookie域也很重要,即一个不会和站点分享cookie的域。它每次可以使用更少的字节向服务器发送图片请求。
然后,将指向图片、样式表和JavaScript的链接均匀分发至有效的资源托管。很重要的一点是,总是通过同一个资源托管来获取相同的资源,否则该资源就会被多次下载。很明显,只有在你拥有一个可支配的框架去处理这些繁重的工作,并排除人为引发的错误时,上述的解决办法才是可行的。Compass使资源托管变得非常容易!
3.1 使用资源托管生成URL
在默认情况下,资源托管在Compass项目中是关闭的,但是你可以告诉Compass如何在资源托管上分发资源,从而开启资源托管。例如,为了在四个子域中分发资源,你需要在Compass配
置中添加以下Ruby代码:
asset_host do |asset| host_number = (asset.hash % 4) + 1 "http://img-#{host_number}.example.com" end
下面进行解释。正如你在前一章中学到的,你应该使用Compass的资源URL辅助器来编写所有的资源引用。如果你已经遵循了这条最佳方式,其实就已经对资源托管有了一些不错的实践。这里,你仍然可以编写下面的CSS代码:
#logo { background-image : image-url(“logo-small.png”) }
你在配置中定义的asset_host函数接收一个叫做asset的参数,它将被完全解析为指向资源的HTTP绝对路径。根据你的其他配置,解析后的路径格式应该类似/images/logo-small.png。asset_host函数的任务是返回资源生成URL的协议和主机地址。尽管你可以自由地运用任何满足需求的逻辑,但是前面的例子在通常情况下已经足够了。首先,asset.hash会给你一个数字来唯一地表示asset字符串。其次,取模运算符(%)会返回其除4以后的余数,该余数是一个0到3之间的整数。最后,它通过每次增加1来进行基于1的计数。在第二行代码中,将host_name插入一个字符串来生成合适的返回值。函数中的最后一个值是实际的返回值,这里不需要显式地指明return。接着,Compass会将该资源托管值与被传入的地址和任何缓存相连接,来生成完整的URL:
#logo { background-image: url(‘http://img-3.example.com/images/logo-small.png?1298578273‘); }
使用资源托管可以显著地减少客户端渲染时间。
3.2 避免内容警告和基于域的资源相混合
如果你的站点支持SSL访问,同时你想要使用资源托管,非常重要的一点是确保你的用户不会从浏览器中接收到不安全资源的警告。处理这个问题的最佳方式是使用相对于协议的URL:
#logo { background-image : url(‘//assets3.example.com/images/logo-small.png?1298578273’) ; }
当浏览器遇到一个相对于协议的URL,它会使用进行最初请求时的协议(对样式表的请求)。为了配置Compass在资源托管时使用一个相对于协议的URL,你需要在配置中添加以下代码:
asset_host do |asset| host_number = (asset.hash %4)+1 "//img-#{host_number}.example.com" end
如果你决定在HTML标记中使用相对于协议的URL,有一点需要注意。IE6和IE7中的一个bug会导致一个指向相对于协议URL的样式表<link>标签被下载两次。
4. 内联dataURI
在CSS中使用data URI时,你可能会使用一个Web服务来上传图片并输出相应的data URI,然后对需要内嵌的每个图片重复这一过程,但是这一的做法耗时耗力而且难以维持。通过使用Compass,处理内嵌图片和其他资源简直是小菜一碟:
.icon { background : inline-image(“black-dot.png”) ; }
Compass可以基于图片的扩展名找出大多数图片格式的MIME类型。但是如果Compass没有识别出图片的扩展名,并且扩展名和MIME类型的第二部分不相同,你可以显示地提供MIME类型:
.icon { background : inline-image(“black-dot.bitmap”,“image/bmp”) ; }
既然Compass可以如此简单地处理内嵌图片,并且能够通过避免额外的数据往返带来诸多好处,为什么我们不一直时用这种方法呢?原因有以下几点:
● 体积膨胀——base-64编码算法的效率并不如普通的二进制编码。
● 缓存——即使这样的做法加快了速度,但是内联图片会增加你的CSS文件体积。
● 浏览器支持——IE6和IE7并不支持data URI,IE8支持的data URI上限为32KB。
5. 选择器性能
5.1 积少成多的问题
选择器的性能之战主要集中在两个方面:修剪和匹配。在修剪方面,浏览器迅速确定并排除所有不会匹配某一个特定元素的选择器。在最低限度上,浏览器会查看关键选择器,来决定这个选择器能否被修剪。最近,浏览器已经开始引入新的修剪启发式方法,比如ID作用域法。
5.2 过分嵌套的危险
紧凑易读的Sass文件有时可能变成巨大的CSS文件,因此非常重要的一点是,在编写Sass时要时刻记住最终生成CSS文件的尺寸和复杂性。特别是Sass新手倾向于使用嵌套选择器来复制HTML结构。这种方法有其确定性。最终,你将会陷入一个比内联样式更难维护的情形中,即使最小的标记修改都会破坏你的设计。而且,由于嵌套时的默认连接符是后代连接符,而且关键选择器通常是一个元素选择器,这意味着你编写的样式正在生成最无效的选择器。为了帮助你识别异常膨胀的样式表,Compass提供了一个stats命令。要实用stats命令,必须首先安装一个叫做css_parser的Ruby gem:
$gem install css_parser
然后运行Compass的stats命令:
$ compass stats