前端缓存也就是HTTP缓存机制是前端性能优化很重要的一点,而前端本地存储和缓存却是不一样的,但对于新手的确有弄混淆的可能。本文详细记录它们的概念与特点
HTTP缓存,可以从缓存位置,获取缓存方式来学习
查找缓存优先级会依次从上到下匹配,如果都没命中那么才会去请求网络资源
一个服务器与浏览器之间的中间人角色,如果网站中注册了service worker那么它可以拦截当前网站所有的请求,进行判断(需要编写相应的判断程序),如果需要向服务器发起请求的就转给服务器,如果可以直接使用缓存的就直接返回缓存不再转给服务器。从而大大提高浏览体验。
内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验。
Disk Cache就是存储在磁盘中的缓存,从存取效率上讲是比内存缓存慢的,但是他的优势在于存储容量和存储时长。一般来说查到的观点是比较大的js、CSS文件会直接被丢进磁盘,反之丢进内存;内存使用率比较高的时候,文件优先进入磁盘。而在实际缓存使用中,Disk Cache 覆盖面基本是最大的
Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令。
浏览器第一次向服务器发起该请求后拿到请求结果后,将请求结果和缓存标识存入浏览器缓存,浏览器对于缓存的处理是根据第一次请求资源时返回的响应头来确定的
满足获取缓存条件情况下,不会向服务器发送请求,直接从缓存中读取资源
Expires即过期时间,存在于服务端返回的响应头中,告诉浏览器在这个过期时间之前可以直接从缓存里面获取数据,无需再次请求。但是服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差,所以在HTTP1.1被Cache-Control替代,现在一般用于兼容
Cache-Control有很多属性,不同的属性代表的意义也不同,可以多个命令配合灵活使用。
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,协商缓存可以通过设置两种 HTTP Header 实现:Last-Modified 和 ETag 。
协商缓存需要进行对比判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了
服务器在响应请求时,会告诉浏览器资源的最后修改时间。
if-Modified-Since: 浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中获取信息即可。 从字面上看,就是说:从某个时间节点算起,是否文件被修改了
服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)
If-None-Match: 再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match则与被请求资源的唯一标识进行对比。
精确性,Etag要优于Last-Modified
性能上,Etag要差于Last-Modified,Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。
Etag / If-None-Match优先级高于Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。
前端本地存储有cookie、localStorage 、 sessionStorage、IndexedDB等等,但常用的也就cookie、localStorage 、 sessionStorage。所以可以直接分析这三种本地存储的特性,可以从存储大小、数据有效性、作用域、通信来对比
存储大小
数据有效性
作用域
通信
cookie与Web Storage包括其他本地存储各有优缺点,比如cookie容量太小,存在安全缺陷并且有一定的性能缺陷,Web Storage作为为了本地存储而诞生,所以无法参与通信,还有例如IndexDB等,兼容性还不是很好,所以我们需要在合适的场景灵活选择