阅读 181

浏览器缓存与Lru-Cache(浏览器缓存与cookie的区别)

思考

  • 浏览器缓存是什么样的行为?

  • Lru-Cache是什么?和浏览器缓存有什么关系?

浏览器缓存

  • 定义:

    • 浏览器将网络资源存储在本地的一种行为

  • 存储位置:

    • 存储类型:非脚本类型,比如css

    • 不会被清除-退出进程时

    • 存储类型:一般的脚本、字体、图片等

    • 何时被清除:退出进程时(关闭tab页面)

    • Service Worker离线缓存JS运行在主线程外(这也是无法直接访问DOM的原因),达到离线缓存网络代理等目的

    • memory cache内存默认存储位置

    • disk cache磁盘

    • prefetch cache预取,被标记为prefetch的资源,会在浏览器空闲时间被加载

    • push cache推送缓存,只在session中存在

  • 缓存的过程:

    • 字段相关:

    • 设置:

    • 再次请求时,携带之前的Last-Modified

    • 服务器对比Last-Modified-SinceLast-Modified,对应返回;

    • Last-Modified:响应时,返回该资源最后被修改的时间缓存标识

    • Etag:响应时,返回当前资源的唯一标识缓存标识

    • If-Modified-Since

    • If-None-Match再次请求时,携带之前的Etag,服务器识别该字段,对比Etag,一致返回304;使用缓存资源;否则返回200和新资源

    • 资源没更改:返回304,读取本地资源;

    • 资源更改:返回200和新资源

    • 携带本地资源的Last-Modified,服务器对比:

    • 携带本地资源的Etag标识,服务器对比:

    • 缓存字段相关:

    • 设置:

    • 注意点cache-control时间段需与服务器资源更新错开

    • public: 都可缓存

    • private:仅客户端可缓存

    • no-cache客户端缓存; 服务端是否缓存需要验证

    • no-store:不使用缓存

    • max-age:缓存保质期

    • expires:缓存到期时间---通过本地时间判断

    • cache-control:使用max-age相对时间

    • pragma:禁用缓存

    • 根据请求头参数,符合强缓存则返回200,从本地缓存读数据;

    • 否则请求头携带响应参数,判断是协商缓存则返回304;否则返回新资源

    • 首次访问:根据响应头中字段expirespragma或者cache-control,判断是否缓存以及缓存位置

    • 第二次访问:

    • 强缓存:访问URL地址时,直接从缓存中读取资源,返回200状态码

    • 协商缓存:浏览器携带缓存标识发起请求,由服务器决定是否使用缓存;一般是在强缓存失效后

  • 缓存过程决定于:通过Cache-Control验证强缓存是否可用

  • 缓存方案选择

    • contenthash:由文件内容生成的hash不同内容得到不同hash

    • 推荐使用理由:生产环境中打包,第一次访问后会缓存;第二次打包发布后,刷新还是之前的资源(名字相同);output文件名加上哈希值

    • HTML类型:协商缓存

    • CSS、JS、图片:强缓存

    • 文件名带上hash值---hash值修改则第一时间请求最新资源

    • 最佳:减少请求、更多使用本地资源---尽可能命中强缓存、同时更新版本时让客户端缓存失效

    • 在webpack中打包的应用:哈希值

浏览器缓存淘汰策略方式之一:LRU
  • 缓存淘汰策略:一种防止缓存空间占满的方式,对数据进行保留、移除

  • LRU(Least Recently Used):最近最少使用缓存淘汰策略,根据数据历史访问记录进行淘汰数据。

    • 获取排位第一的键值map.keys().next()---淘汰最近没被访问key

    • 原理:2.5版本后的vuekeep-alive新增max属性:代表最多可缓存组件实例数;新增缓存实例会优先淘汰最近没被访问的实例

    • 实现:

    • 判断cache是否已缓存,是则直接获取移除keys中对应key放入keys数组最后一位

    • 否则进行缓存实例

    • keys长度大于max时,移除keys[0]缓存

    • cache对象:保存缓存组件的实例和key

    • keys数组:保存缓存组件的key

    • 渲染一个缓存实例时:

    • 关键思想:数据最近被访问过,则代表将来被访问几率更高---优先淘汰最近没被访问的数据

    • 在vue组件中的应用:keep-alive的缓存组件(切换组件时不卸载)

    • 举例:实现LRU缓存机制

class LRUCache {
    constructor(capacity){
        this.capacity = capacity
        this.map = new Map()
    }
    get(key){
        let val = this.map.get(key) //获取key对应val
        if(typeof val === 'undefined') return -1 
        //被访问,修改key的位置
        this.map.delete(key)
        this.map.set(key, val)
        return val
    }
    put(key, val){
        if(this.map.has(key)){
            this.map.delete(key)
        }
        this.map.set(key, val)
        
        //超出限制,优先淘汰
        let keys = this.map.keys()
        if(this.map.size > this.capacity){
            this.map.delete(keys.next().value)
        }
    }
}


作者:用户8249761345499
链接:https://juejin.cn/post/7034024330728046606

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐