大部分网站的响应时间都花在HTTP请求,尤其是资源文件请求。
当然,HTTP 1.1 中已经支持了持久连接-keep-alive
,即一个TPC/IP连接中,可以连续发起多次HTTP请求。随后,采用“管线化”技术,能够做到同时并行发送多个HTTP请求,而不需要一个接一个等待响应(Chrome目前支持在一个域名domain下,同时发起6个并行的HTTP请求)。尽管这样,为了进一步提高网站性能,还是需要考虑如何有效的减少HTTP请求数量。
1. 图片:雪碧图,图标字体文件,data:url
优化图片有很多方式,除了压缩,最常见得就是雪碧图,即把多张小图片合并为一张图,利用CSS -background-position
调整图片显示位置。这种方式适用面比较广泛,缺点是,如果一张小图,需要N个颜色,就必须做N个不同颜色的小图,合并到大图里面。
所以,如果需要大小统一并颜色自定义的图片,那么,图标字体文件最好不过了。比如流行的font-awesome(http://fontawesome.io/), icomoon(https://icomoon.io/, 支持图片自定义)等等。只需要引入字体文件,然后即能够随心所欲的使用各类图片,利用CSS定义图标颜色。
data:url模式可以在页面中渲染图片但无需额外的HTTP请求,格式如下:
代码语言:javascript复制<img scr="data:image/jpg;base64, xxxxxxxxxxxxxxxx">
这个的缺点是,如果一张图片在多个页面被用到,无法利用浏览器缓存。为了解决这个问题,我们可以换个思路,把图片数据放在CSS文件里面定义,比如:
代码语言:javascript复制.imageA {
background-image: url(data:image/jpg;base64, xxxxxxxxxxxxxxxx);
}
这样即可以利用浏览器缓存技术缓存CSS文件,又可以避免额外的图片请求。
注意:移动端不建议用src="data:image..."
,性能非常不好。
2. 合并JS和CSS文件
这个是最常用的做法。
利用项目构建工具,如gulp, grunt, webpack等等,都可以做到JS或者CSS文件的压缩,合并。只不过,合并后文件大小如何,需要斟酌而定。如果仅仅为了减少HTTP请求开销,而下载一个巨大的JS或CSS,反倒会延长网站渲染时间,导致白板或者页面卡顿。
代码语言:javascript复制小贴士:
HTTP 1.1默认在request header里面开启gzip。
使用gzip编码来压缩HTTP响应包,由此可以减少网络响应时间。
例子:Accept-Encoding:gzip,
3. 充分利用浏览器缓存
如果图片或者脚本,样式文件内容比较固定,不经常被修改,那么,尽可能利用缓存技术,减少HTTP请求次数或文件下载次数。
命中浏览器缓存分为两类:强缓存,协商缓存。
- 强缓存:不会发起HTTP请求,直接从浏览器缓存中读取文件。
- HTTP 1.0中,采用
Expires
头指定资源过期时间; - HTTP 1.1中,采用
Cache-Control: max-age
指定资源被缓存多久;
- HTTP 1.0中,采用
- 协商缓存:向服务器发起HTTP请求,如果资源文件并未更新,response响应码即为304,随后从浏览器缓存中下载该文件,并不会从服务器下载。
- HTTP 1.0中,采用
Last-Modified
(response header)和If-Modified-Since
(request header)来指定资源过期时间; - HTTP 1.1中,采用
E-Tag
(response/request header)和If-None-Match
来决定该资源是否过期;
- HTTP 1.0中,采用
哪怕是协商缓存,一旦命中,这个HTTP请求响应速度也是极快的。
当然,如何配置浏览器缓存,大多是后台资源服务器控制的。比如,通常我们建议将共有图片,第三方JS插件库或者CSS放到CDN(内容发布网络)上,不仅仅因为CDN的分布式特性可以加快资源文件下载速度,而且,一般CDN服务器都做了缓存配置,可以充分浏览器缓存。
代码语言:javascript复制小贴士:
如果用JQuery动态加载脚本文件,或者请求其他类型资源文件,可以设置```cache```属性。
cache为true时,开启缓存;反之,JQuery自动在请求上加后缀,强行从服务器重新下载资源文件。
代码如下:
$.ajaxSetup({
cache: true //开启缓存
});
小结
网站性能优化是一个长期过程,一点点做起,最终总会见到成效。系列文章还将继续......