浏览器缓存的位置

缓存位置的类型

缓存位置有四种,各自有优先级,当依次查找缓存且都没有命中的时候,才会去请求网络。

  1. Service Worker
  2. Memory Cache
  3. Disk Cache
  4. Push Cache

Service Worker

  • Service Worker 是一个服务器与浏览器之间的中间人角色,如果网站注册了Service Worker就可以拦截当前网站所有的请求,进行判断(需要编写相应的判断程序),需要向服务器发起请求的就转给服务器,可以直接使用缓存的就直接返回缓存不再转给服务器。从而大大提高浏览体验。
  • Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。基于h5的web worker,所以绝对不会阻碍当前js线程的执行。
  • 最重要的工作原理就是:后台线程:独立于当前网页线程;网络代理:在网页发起请求时代理,来缓存文件;
  • 使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。
  • 1.开发者工具中的Application中查看是否使用Service Worker;2.被Service Worker缓存的文件,可以在Network中看到Size项为 from Service Worker;3.也可以在Application的Cache Storage中查看缓存的具体内容;
  • Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

Memory Cache

  • Memory Cache是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的脚本等。再次访问时不会请求服务器。
  • 读取内存中的数据肯定比磁盘快
  • 缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。再次重新打开相同页面时不会出现from memory cache的情况
  • 内存缓存中有一块重要的缓存资源是preloader相关指令下载的资源。总所周知preloader的相关指令已经是页面优化的常见手段之一,它可以一边解析js/css文件,一边网络请求下一个资源。
  • 内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验。

Disk Cache

  • Disk Cache是存储在磁盘中的缓存。再次访问时不会请求服务器。
  • 读取速度慢点
  • 资源不会随着该页面的关闭而释放掉,比之 Memory Cache 胜在容量和存储时效性上
  • Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自 Disk Cache

Push Cache

Push Cache(推送缓存)是 HTTP/2 中的内容,在国内能够查到的资料很少,有以下结论:

  • 所有的资源都能被推送,并且能够被缓存,但是 Edge 和 Safari 浏览器支持相对比较差
  • 可以推送 no-cache 和 no-store 的资源
  • 一旦连接被关闭,Push Cache 就被释放
  • 多个页面可以使用同一个HTTP/2的连接,也就可以使用同一个Push Cache。这主要还是依赖浏览器的实现而定,出于对性能的考虑,有的浏览器会对相同域名但不同的tab标签使用同一个HTTP连接。
  • Push Cache 中的缓存只能被使用一次
  • 浏览器可以拒绝接受已经存在的资源推送
  • 你可以给其他域名推送资源

Service Worker使用流程

注册Service worker,在index.html加入以下代码

/* 判断当前浏览器是否支持serviceWorker */
    if ('serviceWorker' in navigator) {
        /* 当页面加载完成就创建一个serviceWorker */
        window.addEventListener('load', function () {
            /* 创建并指定对应的执行内容 */
            /* scope 参数是可选的,可以用来指定你想让 service worker 控制的内容的子目录。 在这个例子里,我们指定了 '/',表示 根网域下的所有内容。这也是默认值。 */
            navigator.serviceWorker.register('./serviceWorker.js', {scope: './'})
                .then(function (registration) {
 					console.log('ServiceWorker registration successful with scope: ', registration.scope);
                .catch(function (err) {
 					console.log('ServiceWorker registration failed: ', err);
                });
        });
    }

安装worker:在我们指定的处理程序serviceWorker.js中书写对应的安装及拦截逻辑

/* 监听安装事件,install 事件一般是被用来设置你的浏览器的离线缓存逻辑 */
this.addEventListener('install', function (event) {
    /* 通过这个方法可以防止缓存未完成,就关闭serviceWorker */
    event.waitUntil(
        /* 创建一个名叫V1的缓存版本 */
        caches.open('v1').then(function (cache) {
            /* 指定要缓存的内容,地址为相对于跟域名的访问路径 */
            return cache.addAll([
                './index.html'
            ]);
        })
    );
});
/* 注册fetch事件,拦截全站的请求 */
this.addEventListener('fetch', function(event) {
  event.respondWith(
    // magic goes here
    /* 在缓存中匹配对应请求资源直接返回 */
    caches.match(event.request)
  );
});

Service Worker是有对应的事件名进行捕获的,为:

  1. self.addEventListener(‘install’, function(event) { /* 安装后… */ });
  2. self.addEventListener(‘activate’, function(event) { /* 激活后… */ });
  3. self.addEventListener(‘fetch’, function(event) { /* 请求后… */ });
    基本上,目前Service Worker的所有应用都是基于上面3个事件的,例如,本文要介绍的缓存和离线开发,'install’用来缓存文件,'activate’用来缓存更新,'fetch’用来拦截请求直接返回缓存数据。三者齐心,构成了完成的缓存控制结构。

注意事项

  • Service worker运行在worker上下文 --> 不能访问DOM
  • 它设计为完全异步,同步API(如XHR和localStorage)不能在service worker中使用
  • 出于安全考量,Service workers只能由HTTPS承载
  • 在Firefox浏览器的用户隐私模式,Service Worker不可用
  • 其生命周期与页面无关(关联页面未关闭时,它也可以退出,没有关联页面时,它也可以启动)

访问缓存优先级(三级缓存原理 )

  1. 先在内存中查找,如果有,直接加载。
  2. 如果内存中不存在,则在硬盘中查找,如果有直接加载。
  3. 如果硬盘中也没有,那么就进行网络请求。
  4. 请求获取的资源缓存到硬盘和内存。

chrome控制台Network中size的三种状态

  1. from memory cache:从内存中拿到的资源
  2. from disk cache:从磁盘中读取到的资源
  3. 资源本身大小数值:当http状态为200是实实在在从浏览器获取的资源,当http状态为304时该数字是与服务端通信报文的大小,并不是该资源本身的大小,该资源是从本地获取的

统计表

状态类型说明
200form memory cache不请求网络资源,资源在内存当中
200form disk ceche不请求网络资源,在磁盘当中
200资源大小数值从服务器下载最新资源
304报文大小请求服务端发现资源没有更新,使用本地资源
  • 由此可见样式表一般在磁盘中,不会缓存到内存中去,因为css样式加载一次即可渲染出网页
  • 但是脚本却可能随时会执行,如果脚本在磁盘当中,在执行该脚本需要从磁盘中取到内存当中来,这样的IO开销是比较大的,有可能会导致浏览器失去响应

Firefox的缓存策略

  • 在Firefox下并没有from memory cache以及from disk cache的状态展现,相同的资源在chrome下是from disk/memory cache,但是Firefox统统是304状态码
  • 即Firefox下会缓存资源,但是每次都会请求服务器对比当前缓存是否更改,chrome不请求服务器,直接拿过来用
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值