zoukankan      html  css  js  c++  java
  • 浏览器缓存机制总结

    浏览器缓存机制也就是我们常说的HTTP缓存机制,根据HTTP报文的缓存标识来响应的;

    简单来说,浏览器缓存其实就是浏览器保存通过HTTP获取的所有资源,是浏览器将网络资源存储在本地的一种行为;

    从缓存位置上来划分的话,分为四种,并且各自有优先级,当依次查找缓存且都没有命中的时候,才会去请求网络:

    1、Server Worker

    2、Memory Cache:

    MemoryCache顾名思义,就是将资源缓存到内存中,等待下次访问时不需要重新下载资源,而直接从内存中获取。Webkit早已支持memoryCache。
    目前Webkit资源分成两类,一类是主资源,比如HTML页面,或者下载项,一类是派生资源,比如HTML页面中内嵌的图片或者脚本链接,分别对应代码中两个类:MainResourceLoader和SubresourceLoader。虽然Webkit支持memoryCache,但是也只是针对派生资源,它对应的类为CachedResource,用于保存原始数据(比如CSS,JS等),以及解码过的图片数据。

    3、Disk Cache:

    DiskCache顾名思义,就是将资源缓存到磁盘中,等待下次访问时不需要重新下载资源,而直接从磁盘中获取,它的直接操作对象为CurlCacheManager。

    4、Push Cache

    网络请求

    Memory cache | Disk cache 对比:

    相同点 只能存储一些派生类资源文件 只能存储一些派生类资源文件
    不同点 退出进程时数据会被清除 退出进程时数据不会被清除
    存储资源 一般脚本、字体、图片会存在内存当中 一般非脚本会存在内存当中,如css等

    像CSS文件加载一次就可渲染出来,我们不会频繁读取它,所以它不适合缓存到内存中,但是js之类的脚本却随时可能会执行,如果脚本在磁盘当中,我们在执行脚本的时候需要从磁盘取到内存中来,这样IO开销就很大了,有可能导致浏览器失去响应;

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

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

    浏览器缓存的优点

    1、减少了冗余的数据传输;

    2、减少了服务器的负担,大大提升了网站的性能;

    3、加快了客户端加载网页的速度;

    浏览器缓存分为 强缓存和协商缓存 两种:

    浏览器向服务器请求资源时,首先判断是否命中强缓存,再判断是否命中协商缓存;

    1、强缓存:

    强缓存可以通过设置两种HTTP Header来实现: Expires 和 Cache-Control

     如果缓存过期了,就需要发起请求验证资源是否有更新。

    1.1 Expires:

    该字段为http1.0的规范,它的值为GMT格式的时间字符串,

    比如  Expires:Mon,18 Oct 2066 23:59:59 GMT,这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,

    由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,或者客户端手动修改了系统时间时,就会导致缓存混乱;

    1.2 Cache-Control:

    该字段是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control:max-age=3600,代表着资源的有效期是 3600 秒。cache-control 除了该字段外,还有下面几个比较常用的设置值:

    no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。

    no-store:禁止使用缓存,每一次都要重新请求数据。

    public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。

    private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

    注意:Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高。

    2、协商缓存

    当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。

    这里的 header 中的信息指的是 Last-Modify/If-Modify-Since 和 ETag/If-None-Match.

    2.1 Last-Modify/If-Modify-Since

    浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。

    当浏览器再次请求该资源时,request请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify。服务器收到 If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。

    如果命中缓存,则返回 304,并且不会返回资源内容,并且不会返回 Last-Modify。

    缺点:

    Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间,

    也就是 短时间内资源发生了改变,Last-Modified 并不会发生变化。

    周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为,因此便有了 ETag。

    2.2 ETag/If-None-Match

    与 Last-Modify/If-Modify-Since 不同的是,Etag/If-None-Match 返回的是一个校验码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器上送的 If-None-Match 值来判断是否命中缓存。

    与 Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。

    注意:Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

    小结:

    当浏览器再次访问一个已经访问过的资源时,它会这样做:

    1.看看是否命中强缓存,如果命中,就直接使用缓存了。

    2.如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。

    3.如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存。

    4.否则,返回最新的资源。

  • 相关阅读:
    第四章 生命周期函数-- 34 生命周期函数-组件运行和销毁阶段的钩子函数
    第三章 指令-- 31 指令-定义私有指令,32 指令-指令函数的简写形式
    第三章 指令-- 30 指令-使用钩子函数的第二个binding参数拿到传递的值
    第三章 指令-- 29 指令-自定义全局指令让文本框获取焦点
    bindActionCreators作用
    Object.prototype.toString.call()
    C语言基础 (4) 原码反码补码与数据类型
    React中的setState(obj)
    清除行内元素中间的空白
    分清encodeURIComponent encodeURI 和 escape
  • 原文地址:https://www.cnblogs.com/fmixue/p/15153324.html
Copyright © 2011-2022 走看看