美文网首页
浏览器的缓存机制

浏览器的缓存机制

作者: 前端小白的摸爬滚打 | 来源:发表于2021-09-26 22:45 被阅读0次

    浏览器的缓存机制

    缓存是性能优化的关键手段,可以大大的减少网络延迟,大大提高性能


    image

    memory cache 和 disk cache

    memory cache

    是内存中的缓存,主要包含当前页面下载的资源,图片、样式、脚本等等。读取内存上的资源比读取硬盘上的更快;但是内存缓存的时间短,当前 tab 也关闭时内存也会被释放

    因为内存有限所以并不是所有的资源都可以存放在内存当中,一般存放的都是 preloader 相关的资源

    disk cache

    所有的资源都可以存放在硬盘上,读取速度比内存慢一点

    浏览器会根据 http 请求的响应头决定哪些资源需要缓存,哪些需要向服务器重新发送请求

    浏览器是如何知道缓存哪些文件的

    响应头中与缓存相关的字段

    • Expires

    • Cache- Control

    • Last-Modified/If-Modified-Since

    • Etag/If-None-Match

    前两者是强缓存,后两者是协商缓存

    强缓存

    强缓存是不需要向服务器发送请求的,可以直接返回 200,使用浏览器的缓存,返回的状态码有 from memory cache/from disk cahce.

    通过 Expires 和 Cache-Control 来实现,Cache-Control的优先级更高

    Expires

    是 http1.0 中提出的,值是 GMT 时间,是一个绝对时间,在该时间之前表示缓存有效,可以直接使用浏览器总的缓存,不需要向服务器请求资源

    缺点

    和本地时间有关,如果调整了本地时间那么缓存就有可能会失效,所以就有了 Cache-Control

    Cache-Control

    http1.1 中提出的用于控制资源缓存的首部

    • public

    表示资源可以被任意地方缓存,CDN、代理服务器、浏览器

    • private

    表示资源只能被浏览器所缓存,私人缓存

    • max-age

    相对时间,单位是秒

    相对于资源返回的时间(浏览器记录了这个时间)而言,在这个时间范围之内,缓存都有效

    • max-stale

    能容忍的最大过期时间,表示浏览器可以接受已经过期的资源,但是过期的时间不能超过我们设置的时间,单位是秒,如果不设置,表示可以接受任意过期的资源

    • no-cahce

    不是代表资源不缓存,资源也可以被缓存,只不过浏览器不会直接使用缓存,而是会使用协商缓存来验证资源是否有效,然后来决定是否使用缓存中的资源

    • no-store

    所请求的资源不会被缓存,每次都去服务器请求最新的资源

    • s-maxage

    和 max-age 相同,只不过设置的是代理服务器缓存的有效时间

    • max-fresh

    表示资源的最小新鲜度,所请求的资源在我们设置的时间内有效

    • must-revalidate

    表示只有校验缓存中的文件是最新的才会使用缓存中的资源

    协商缓存

    协商缓存指的是强缓存失效后,浏览器携带缓存标识向服务器发送请求,由服务器根据缓存标识来决定是否使用缓存

    缓存有效

    返回 304 和空的响应体,表示使用缓存中的资源

    image

    缓存失效

    返回200和新的资源以及缓存标识


    image

    协商缓存使用的是【Last-Modified、If-Modified-Since】和【Etag、If-None-Match】这两对http header来进行管理的

    Last-Modified

    http1.0中提出
    浏览器第一次请求资源的时候,返回该资源时,会在响应头中添加一个Last-Modified首部,表示该资源的最后修改时间。浏览器下次请求该资源的时候,会自动在请求头中添加一个If-Modified-Since的头部,只为Last-Modified的值,服务器收到这个请求的时候会取出If-Modified-Since的值和所请求的资源的最新修改时间相比较,如果一直则返回304和空的响应体,表示使用缓存中的资源,如果小于最新修改时间,则返回200+最新的资源以及缓存标识

    缺点

    • 只能精确到秒,有些资源可能会在一秒中修改了多次,此时就会导致浏览器使用的还是旧的资源
    • 我们可能只是打开了文件,但是并没有修改,即使是这样Last-Modified的值还是会发生改变,导致缓存失效

    针对Last-Modified的缺点,就出现了Etag

    Etag

    http1.1中提出
    服务器根据指定资源的内容生成的唯一标识,优先级高于Last-Modified,只要资源的内容发生改变,Etag就会重新生成。浏览器在下一次请求资源的时候就会将该资源的Etag放入request header中的If-None-Match首部中。服务器会比较客户端传递过来的If-None-Match的值和服务器上该资源的Etag是否一致,就可以很好的判断该资源是不是最新的。如果服务器发现 ETag 匹配不上,那么直接以常规 GET 200回包形式将新的资源(当然也包括了新的 ETag)发给客户端;如果 ETag 是一致的,则直接返回304知会客户端直接使用本地缓存即可。

    缓存机制总结

    强缓存优先于协商缓存,强缓存有效则直接使用缓存中的资源,不会发送请求到服务器,否则则使用协商缓存。然后根据协商结果判断返回304还是200+新的资源

    没有设置缓存的时候浏览器默认的缓存策略

    缓存时长 = (访问时间 - 最后一次修改时间) / 10

    用户行为对浏览器缓存的影响

    • 刷新浏览器:强缓存失效,协商缓存有效,浏览器携带Cache-Control: max-age=0以及协商缓存相关首部去请求服务器,看是否可以使用本地资源

    • 强制刷新:协商缓存和强缓存都失效,浏览器携带Cache-Control: no-cache首部请求服务器(为了兼容还会设置Pragma: no-cache)

    缓存的缺点

    可能由于缓存导致用户看到的是旧的页面,无法看到在缓存有效期间开发者更新的功能
    解决方式:

    • 每次版本更新手动修改引用的脚本文件的版本号
    • 使用打包工具,给生成的静态资源的文件名添加hash值

    相关文章

      网友评论

          本文标题:浏览器的缓存机制

          本文链接:https://www.haomeiwen.com/subject/pzycnltx.html