http缓存
http缓存分为强缓存、协商缓存。规则如:juejin.cn/post/694137… 。常用的前端页面中采用的缓存方案:
- 频繁变动的资源,比如html,采用协商缓存
- css、js、图片资源等采用强缓存 使用hash命名
webpack中的hash
webpack中有三种hash:hash、chunkhash、contenthash。每种hash都有自己的作用,使用场景如下。
- hash:项目级别的hash。项目中只要有文件变化,该hash就会变化。同时所有文件都公用该hash。所以所有资源都将重新请求服务器,导致没有改动资源的加载浪费。所以不建议使用
- chunkhash:属于入口文件级别的hash,会根据入口文件entry的依赖进行打包。所以项目主入口文件js与其对应依赖文件css被打包在同一模块,公共相同的chunkhash。但是公共库由于是不同的模块,所以有单独的chunkhash。
- contenthash:文件内容级别。其会根据文件内容的变化而变化。在chunkhash中我们讲到【项目主入口文件js与其对应依赖文件css被打包在同一模块,公共相同的chunkhash】,假设css没有任何更改,css文件仍旧会被重复构建。此时,针对css使用contenthash后,只要内容不变就不会被重复构建。
浏览器缓存
当一个资源准备加载的时候,浏览器会按照如下顺序进行判断:
- 首先找到Memory cache,如果资源在内存中存在,直接从内存中读取。
- 内存中没有找到,去磁盘中查找,找到便从磁盘中读取
- 磁盘中如果也没有找到,进行网络请求,并将请求后符合条件的资源存入内存和磁盘中
Memory cache
内存缓存。他的优点是获取速度快、优先级高。从内存中获取资源耗时卫0ms,其缺点也显而易见:声明周期短,当网页关闭后内存就会释放、受限于计算机内存的大小,是有限的。
Dick cache
硬盘缓存。优点是生命周期长,不触发删除操作则会一直存在。缺点是:相对内存缓存来讲读取速度较慢。 Dick cache 会根据保存下来资源的首部字段来判断它们是否需要重新请求,如果重新请求便是强缓存的实效流程。否则便是生效流程。
缓存存储优先级
硬盘缓存会将命中强缓存的js、css、图片等资源都存储起来。但是内存缓存由于其大小受限,所以不能这样做。(再次刷新让内存缓存生效)但是什么类型的资源会被放到内存缓存中在浏览器标准中并没有详尽的描述,只有一些资料中得到的规律以供参考。
- css资源只有很小的概率会被内存缓存,网上给出的非标准解释是:因为css加载一次就可以渲染出来了。我们不会频繁的去读取它。所以它不适合被缓存到内存中。但是js之类的脚本却随时可能会执行,如果脚本在硬盘中,我们在执行脚本的时候,需要从磁盘读取到内存中,这样io开销就很大了,有可能导致浏览器失去响应。
- js资源的执行加载时间会影响其是否被内存缓存。原因是浏览器渲染进程未结束的这段时间里,资源有被存入内存的可能。相反,渲染进程结束后,则不太可能会被存入内存。图片也类似
- preload。指明资源在页面加载完成后即刻需要的。浏览器会在主渲染机制介入前预先加载这些资源,并不阻塞页面的初步渲染。使用preload的资源会一直从磁盘缓存中读取,js、css、图片也是如此。原因是:渲染机制介入前资源不会被内存缓存。
- prefetch:告诉浏览器加载下一页面可能会用到的资源,浏览器会利用空闲状态进行下载并把资源存储到内存缓存中。
Sercice Worker
随着互联网的发展,web应用技术不断发展。其中渐进式应用(pwa)可以支持渐进式增强,让网页在离线的时候仍然可用。在现代浏览器中可以使用新功能,如果新功能不可用,用户仍旧可以获得核心体验。实现以上特性的关键技术就是service worker。
service worker 依赖Cache、Fetch
浏览器存储型缓存方案
- cookie。老牌的存储型缓存。不能超过4kb。同域下的cookie会伴随每一次资源请求的请求头传递到服务端进行验证,所以非用户身份类的数据不建议存储在cookie中
- web storage。session storage、local storage,一般在2.5M-10M之间。web storage存储的数据最终都会转化为字符串类型。
- indexDB。大规模NoSql存储系统,存储能力250M左右。npm上对indexDB封装比较好的包:idb,可以简化原始APi的操作流程。