性能黄金法则
- 只有10%~20%的最终用户响应时间花在下载HTML文档上。
- 剩下的80%~90%时间花在了下载页面中的所有组件(图片、脚本、样式表、Flash等)上。
1、减少HTTP请求
- 例如:图片地图、CSS sprites、内联图片(data:)、合并脚本和样式表。
- 实际应用这些技术估计响应时间可以减少到50%左右。
2、使用内容发布网络
如果应用程序web服务器离用户更近,则一个HTTP请求的响应时间将缩短;
如果组件web服务器离用户更近,多个HTTP请求的响应时间将缩短。
内容发布网络(CDN Content Delivery Network)是一组分布在多个不同地理位置的web服务器,用于更加有效的向用户发布内容。
对于大型的商业网站可以使用CDN服务商,小型的非商业网站可以使用免费的CDN服务。
收费:Akamai、Mirror Image、Limelight、SAVVIS。
开源:Globule、CoDeeN、CoralCDN。
3、添加Expires头
在HTTP 1.0协议中,使用Expires头设置组件的有效时间。
(使用Expires头要求服务器和客户端的时钟严格同步。另外过期日期需要经常检查,
并且未来这一天到来了,还需要在服务器配置中提供一个新的日期。)
Expires:Thu, 04 Nov 2027 15:14:36 GMT
在HTTP 1.1协议中,引入了Cache-Control头来克服Expires的限制,使用方式如下:
Cache-Control: max-age=31536000
可以为图片、脚本、样式表和Flash组件设置长久的Expires头。但是HTML文档不应该使用长久的Expires头,因为它包含动态内容,这些内容在每次用户请求时都将被更新。
4、压缩组件
1、如何压缩?
HTTP1.1开始,可以通过HTTP请求中的accept-encoding头来表示对压缩的支持
accept-encoding:gzip, deflate, sdch
如果web服务器看到请求中有这个头,就会使用客户端列出来的方法中的一种来压缩响应,web服务器通过响应中的 的响应头中content-encoding头来通知web客户端。
content-encoding:gzip
通常推荐使用gzip压缩方式,gzip是最理想的压缩方法。
2、压缩什么?
- 推荐压缩XML、JSON、js脚本、样式表。
- 图片和PDF不应该压缩,应为他们本来就已经被压缩了,试图对他们压缩只会浪费CPU资源,还可能会增加文件大小。
- 压缩的成本:服务端需要额外的CPU周期来完成压缩,客户端需要对压缩文件进行解压缩。
- 通常对大于1KB或者2KB的文件进行压缩。
3、节省
压缩通常能将相应的数据量较少将近70%。
4、配置
配置gzip时使用的模块取决于Apache的版本,Apache1.3使用mod_gzip,而Apache 2.x使用mod_deflate。
5、代理缓存
在服务器的响应头中配置Vary响应头
vary:Accept-Encoding
这将使代理缓存响应的多个版本,为Accept-Encoding请求头的每个值缓存一份。
5、将样式表放在顶部
使用LINK样式的标签将样式表放在文档的HEAD中,可以使页面逐步呈现,并规避白屏和无样式内容闪烁的风险。
为什么会这样?
- 白屏现象源自于浏览器的行为。如果样式表仍在加载,构建呈现树就是一种浪费,因为在所有的样式表加载并解析完毕之前无需绘制任何东西。
- 使用样式表时,页面逐步呈现会被阻塞,知道所有的样式表下载完成。
6、将脚本放在底部
将脚本从页面的顶部移到页面的底部,这样页面既可以逐步呈现,也可以提高下载的并行度。
使用脚本时,对于位于脚本以下的内容,逐步呈现都被阻塞了。将脚本放在页面越靠下的地方,意味着越多的内容能够逐步呈现。
7、避免使用CSS表达式
8、使用外部的JavaScript和CSS
9、减少DNS查找
通过使用Keep-Alive和较少的域名来减少DNS查询。
今天的很多页面都有大量的组件,建议将这些组件分别放到2到4个主机名下面,可以在减少DNS查询和允许高度并行下载之间做出很好的权衡。
Keep-Alive可以重用现有的连接,从而通过避免TCP/IP开销来减少响应时间。还可以减少DNS查询。
10、精简JavaScript
11、避免重定向
12、删除重复脚本
13、配置或者移除ETag
如果缓存的组件过期了,或者用户重新加载页面,浏览器在重用它之前必须首先检查它是否仍然有效。
服务器监测缓存组件的两种方式:
- 比较最新修改日期 Last-Modified If-Modified-Since
- 比较实体标签 ETag If-None-Match
ETag带来的问题?
ETag问题在于通常使用某些组件的属性来构造,这些属性对于特定的服务器来说是唯一的。当浏览器从一台服务器上获取了原始组件,之后又向另外一套不同的服务器发起条件GET请求时,ETag不会匹配。所以在集群的情况下,使用缓存的概率大大降低。
在web服务器上配置ETag,比如Apache的ETag上只包含组件大小和时间戳, IIS上只有时间戳,最好是将ETag完全移除,Last-Modified头可以提供完全等价的信息。如果ETag和Last-Modified同时存在时,ETag的优先级更高,建议移除。