一、HTTP缓存机制
启用浏览器缓存
1.缓存分类
HTTP缓存模型中,如果请求成功会有三种情况
(1)200 from cache:直接从本地缓存中获取响应,最快速,最省流量,因为根本没有向服务器发送请求
(2)304 Not Modified:协商缓存,浏览器在本地没有命中的情况下请求头中发送一定的校验数据到服务端,如果服务端数据没有改变浏览器从本地缓存响应,返回304
快速,发送的数据很少,只返回一些基本的响应头信息,数据量很少,不发送实际响应体
(3)200 OK:以上两种缓存全部失败,服务器返回完整响应。没有用到缓存,相对最慢。
2.本地缓存
浏览器认为本地缓存可以使用,不会去请求服务端
相关Header
Pragma:HTTP1.0时代的遗留产物,该字段被设置为 no-cache 时,会告知浏览器禁用本地缓存,即每次都向服务器发送请求。
Expires:HTTP1.0时代用来启用本地缓存的字段,expires 值对应一个形如 Fri, 05 Jan 2018 06:10:41 GMT 的格林威治时间,告诉浏览器缓存实现的时刻,如果还没到该时刻,表明缓存有效,无需发送请求。
浏览器与服务器的时间无法保持一致,如果时间差距大,就会影响缓存结果。
Cache-Control:HTTP1.1针对Expires时间不一致的解决方案,运用Cache-Control告知浏览器缓存过期的时间间隔而不是时刻,即使具体时间不一致,也不影响缓存的管理。
no-store:禁止浏览器缓存响应
no-cache:不允许直接使用本地缓存,先发起请求和服务器协商
max-age=delta-seconds:告知浏览器该响应本地缓存有效的最长期间,以秒为单位
优先级 Pragma > Cache-Control > Expires
3.协商缓存
当浏览器没有命中本地缓存,如本地缓存过期或者响应中声明不允许直接使用本地缓存,那么浏览器肯定会发起服务端请求。
服务端会验证数据是否修改,如果没有通过浏览器使用本地缓存。
相关Header
Last-Modified:通知浏览器资源的最后修改时间,如 Last-Modified: Sat, 09 Dec 2017 02:48:31 GMT
If-Modified-Since:得到资源的最后修改时间后,会将这个信息通过If-Modifed-Since提交到服务器做检查,如果没有修改,返回304状态码
ETag:HTTP1.1推出,文件的指纹标识符,如果文件内容修改,指纹会改变
If-None-Match:本地缓存失效,会携带此值去请求服务端,服务端判断该资源是否改变,如果没有改变,直接使用本地缓存,返回304
二、缓存策略的选择
1.适合缓存的内容
不变的图像,如logo、图标等;js、css静态文件;可下载的内容,媒体文件。
2.建议使用协商缓存
HTML文件;经常替换的图片;经常修改的js、css文件。
js、css文件的加载可以加入文件的签名来拒绝缓存,如 index.css?签名 或者 index.签名.js
3.不建议缓存的内容
用户隐私等敏感数据
经常改变的api的数据接口
三、Nginx配置缓存策略
1.本地缓存配置
add_header指令:添加状态码为2XX和3XX的响应头信息
语法格式:add_header name value [always];
可以设置 Pragma/Expires/Cache-Control,可以继承
expries指令:通知浏览器过期时长
语法格式:expires time;
为负值时表示 Cache-Control: no-cache;
当为正或者0时,就表示Cache-Control: max-age=指定的时间;
在nginx的配置中可以添加如下代码,分别设置图片缓存 30天和js css缓存12小时。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|PNG|JPG|JPEG|GIF)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 12h; }
当expires设置为max时,会把Expires设置为 "Thu, 31 Dec 2037 23:55:55 GMT",Cache-Control设置到 10 年;
2.协商缓存相关配置
Etag指令:指定签名
语法:etag on | off; 默认是on
如下nginx中设置etag关闭
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|PNG|JPG|JPEG|GIF)$ { etag off; }
四、前端代码和资源的压缩
优势:让资源文件更小,加快文件在网络中的传输,让网页更快的展现,降低带宽和流量开销
压缩方式:JS、CSS、图片、HTML代码的压缩;Gzip压缩
1.JavaScript代码压缩
js压缩的原理一般是去掉多余的空格和回车、替换长变量名、简化一些代码写法等。
常用压缩工具:UglifyJS、YUI Compressor、Closure、Compiler
2.CSS代码压缩
原理跟js压缩原理类似,同样是去除空白符、注释并且优化一些CSS语义规则等
常用压缩工具:YUI Compressor、CSS Compressor
3.HTML代码压缩
不建议使用代码压缩,有时会破坏代码结构,可以使用Gzip压缩。
4.图片压缩
除了代码的压缩外,有时对图片的压缩也是很必要的,一般情况下图片在web系统的比重都比较大。
压缩工具:tinypng、JpegMini、ImageOptiom
5.Gzip压缩
配置Nginx
gzip on | off; #是否开启gzip
gzip_buffers 32 4k | 16 8k #缓冲(在内存中缓冲几块?每块多大)
gzip_comp_level [1-9] #推荐6 压缩级别(级别越高,压缩的越小,越浪费CPU计算资源)
gzip_disable #正则匹配UA 什么样的Uri不进行gzip
gzip_min_length 200 #开始压缩的最小长度
gzip_http_version 1.0 | 1.1 #开始压缩的http协议版本
gzip_proxied #设置请求者代理服务器,该如何缓存内容
gzip_types text/plain application/xml #对哪些类型的文件用压缩 比如txt,xml,html,css
gzip_vary on | off #是否传输gzip压缩标志
以下是Nginx配置gzip代码
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\.";