Gzip 可以使资源加载时,大小缩减到原来的 1/3 。长时间缓存可以让浏览器不加载没有变化的文件。这两者都是前端性能优化的范畴,大家都懂的。
资源文件长缓存
将 Cache-Control 改为 public ,并加上一年的长缓存,配合 MD5 版本号实现长缓存 + 按版本号自动更新:
location /res{
expires 1y;
add_header Cache-Control public;
}
为保证缓存效果,先去掉 Etag (Entity Tag)
浏览器会根据 Entity Tag 判断文件是否被修改过。而观星台用的是多台服务器。由于不同的服务器可能对同一个文件生成不同的 Entity Tag,用户第一次从服务器 A 拿过的文件,第二次从服务器 B 拿时,服务器给出的 Entity Tag 有可能不同。这就会造成重复下载,缓存形同虚设。由于已经有 MD5 插件机制起到了类似 Entity Tag 的效果,所以暂时先禁用掉 Entity Tag。
http{
etag off;
}
Entity Tag 具体的原理
Entity Tags
Entity Tags (ETags) 是 HTTP/1.1 的新特性。在 Conditional GET Requests 中起作用,是一个标识文件特定版本的标记。是除了最后修改时间以外,判断组件是否变化的另一种方式。
图1 Rule 3 提到的 If-Modified-Since 请求判断文件是否已修改
图2 如果第一次请求时服务器返回了 ETags 那么每次的 Conditional GET Request 浏览器都会多一个 If-None_Match 请求头判断 ETags 是否改变
Etags 的问题
如果网站使用多个服务器,Apache 和 IIS 的默认配置都会导致不同服务器的同样文件有不同的 ETags,从而大大增加了不必要的流量。
此外,若 ETags 的优先级高于 Expire Header (本章没说清啥情况下 ETags 的优先级高于 Expire Header),则尽管遵循 Rule 3 为基本不改动的组件设了长 Expire Header ,访问者每次刷新还是会重新下载一次那个组件。很浪费有木有?
解决
要就充分利用 ETags 带来的灵活性,比如根据不同的浏览器给出不同的 ETags (例如谷歌就给中文和英文网站的资源不同的 Etags,可以想象到带来的维护上的方便性);
要么删掉 ETags 。
If-Modified-since 和 Connection: keep alive
首先是一般的 GET 请求和回应的 Headers,如上图所示。向右的箭头是请求,下同。
为了节约浏览和时间,可以压缩后传输。上图所示就是压缩传输的请求和回应的 Headers。压缩传输的概念在《CSS Mastery》里面(读书笔记)也有提到。传输的内容是否压缩的信息就包含在如图所示的 HTTP 头里面。
上图所示是一种有条件的 GET 请求及其回应的 Headers。浏览器在加载图片的时候往往会这样请求。其中, If-Modified-since 后面的内容是向服务器确认浏览器缓存中的内容是否过时。如果不过时,返回的就是如上图所示的 304 Not Modified。
同样,如果过时,返回的就是如上图的 200 OK。
另外,HTTP 的早期实现是,每遇到一个 HTTP 请求就打开一个新的 socket 连接。而 HTTP 的很多请求都是在同一个服务器上的,因此这样比较低效。这时改进的方法是,如上图,向服务器请求时使用 keep-alive 的 Connection header。不需要时发送 Connection: close header。
理论上,HTTP/1.1 是不需要发送上图所示的 keep-alive 信息的,但是很多浏览器依然要求(本书影印版出版日期 2008 年 5 月)。
开启 Gzip 压缩
- 设置最小 1kb 开启 gzip 压缩;
- 开启 gzip_vary ,当用户使用代理服务器的时候,代理服务器会缓存压缩前后两个版本的文件,方便不同浏览器支持情况的用户;
- 将 gzip_http_version 设为 1.0,表明为 HTTP/1.0 以上的协议启用 gzip 压缩;
- 开启 js 、 css 、 xml 和 txt 文件的 gzip 压缩。其中网络图片(png/jpeg/gif)格式本身的压缩率一般都已经够高,不用再加 gzip 压缩,没什么效果还占用资源。对于观星台某些过大的 jpeg 图片,可以选择自动加 gzip 压缩作为折衷方案。但最主要的还是在做图的时候就设置好质量压缩比最高的压缩程度。
- 压缩比例设为 3。最小是 1 ,最大是 10。一般都设为 3。
- 对 IE1-6 不启用压缩,因为对 gzip 压缩支持的不太好,可能会出现闪跳问题(当然我们几乎没有这个类型的访客,可加可不加)。
- 其它未提到的设置保持默认。
http{
gzip on;
gzip_min_length 1k;
gzip_vary on;
gzip_http_version 1.0;
gzip_types text/plain application/x-javascript text/css application/xml image/jpeg;
gzip_comp_level 3;
gzip_disable "MSIE [1-6].";
}