协议

http缓存

关于浏览器缓存可以看看这篇文章:

缓存机制浅析 - 移动端 Web 加载性能优化

最原始的缓存机制:304缓存

一般情况下,浏览器在第一次访问一个静态文件的时候都会把它缓存到本地。但是在第二次请求的时候到底是使用缓存还是重新从服务器下载这个静态文件呢?

理论上来说,如果被缓存的文件在服务器上没有更新过,则可以直接使用缓存;如果被缓存的静态文件已经在服务器上更改过了,则需要重新下载。

因此,只要浏览器能够知道这个文件是否在服务器上已经更新过,则可以判断是使用缓存还是重新下载。

如何进行这个判断呢?

ETag:静态文件标识,相当于文件的MD5。浏览器在第二次访问文件的时候通过询问服务器文件是否有改变。

Last-Modified:文件最后修改时间。第二次访问时通过If-Modified-Since请求头携带这个时间询问服务器文件是否有改变。

优点: 保证浏览器使用的静态文件是最新的静态文件。一旦服务器更新了文件,浏览器就会重新下载。

缺点: 浏览器每次都需要发送一个http请求询问服务器缓存是否更新。虽然这个请求体积非常小,但是建立http连接需要很大的开销,对服务器来说也存在带宽和计算资源的消耗。

说明:Nginx默认对静态文件使用的便是这种机制。

更轻量的缓存机制:200 from cache

304优缺点显而易见,那么我们有没有办法不发送询问请求实现静态文件的更新呢??

如果不发送询问请求而直接使用本地缓存,导致的问题就是服务器文件更新后根本没办法通知浏览器。

要让浏览器直接使用缓存,我们只用满足一个条件:保证浏览器得到的静态文件永远不会被服务器更新。

但是我们的静态文件是不可能用不更新的,因此我们不能再使用原始的静态文件组织方式,一旦静态文件有更新,我们就改变这个文件的文件名。

这样浏览器根本不需要关心缓存的文件是否会被更新,因为服务器保证不会更新同名文件,一旦更新,则会修改文件名,导致文件的url发生改变,从而让浏览器重新请求文件。

那如何让浏览器直接使用缓存而不再发送请求询问静态文件是否更新呢?我们需要使用到cache-control

cache-control: 告诉浏览器缓存静态文件的时间,单位为秒,如cache-control:max-age=315360000代表1年之内直接使用缓存,不再询问服务器是否更新。

这样,浏览器对url未改变的静态文件不再询问服务器是否有更新而直接使用缓存,这种使用方式便的状态吗便是200 from cache

实现200 from cache的具体步骤

优点:理想情况下浏览器访问一个页面只需要1个http请求。通过这个方式,浏览器访问页面的时候只需要从服务器下载页面的html内容,外链的静态文件直接使用本地缓存,只有被服务器更新过的静态文件(已经在html内容里更新了这些文件url)才会被重新下载。

缺点:需要对源代码进行编译,在静态文件的名称中包含MD5值,保证文件改变则文件名也改变。

200 from cache不仅仅可以从硬盘缓存加载(from disk cache),还可以从内存中直接加载(from memory cache),因此在多页面共享静态文件的时候性能非常优秀。

关于浏览器的刷新(chrome测试)

Ajax

在ie里使用ajax的get请求,如果服务器没有返回no-cache,则会缓存请求。也就是说每次请求的内容都是一样的,不管服务器更新没更新。

所以使用$.get或者$.getJSON都需要加上 _t = (+ new Date()) 参数

默认缓存

https://tools.ietf.org/html/rfc7234#section-4.2.2 当没有设置cache-control也没有设置expires,但却设置了last-modified的情况下,文件依然会被默认缓存!感觉这个很容易被忽视掉。