浏览器中的缓存机制

文章类型:Javascript

发布者:hp

发布时间:2024-12-04

一:概述

缓存可以说是性能优化中简单高效的一种优化方式了,它可以显著减少网络传输所带来的损耗。

对于一个数据请求来说,可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三步骤中优化性能。

二:内容

(一)缓存位置

1:Service Worker:

(1)可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的

(2)当 Service Worker 没有命中缓存的时候,我们需要去调用 fetch 函数获取数据,根据缓存查找优先级去查找数据。不管我们是从 Memory Cache 中还是从网络请求中获取的数据,都会显示我们是从 Service Worker 中获取的内容

2:Memory Cache(内存缓存):

(1)读取内存中的数据肯定比磁盘快。但是内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放

(2)内存一定比硬盘容量小得多,操作系统需要精打细算内存的使用

3:Disk Cache(硬盘缓存)

(1)存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上

(2)Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求

4:Push Cache

(1)HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。并且缓存时间也很短暂,只在会话(Session)中存在,一旦会话结束就被释放

5:网络请求

(1)所有缓存都没有命中的话,那么只能发起请求来获取资源

(二)缓存策略

1:强缓存:强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control,(状态码200)

Expires: 是 HTTP/1 的产物,时间过期后会重新请求,修改本地时间会导致缓存失效

Cache-Control 出现于 HTTP/1.1,优先级高于 Expires 。该属性值表示资源会在 30 秒后过期,需要再次请求。

Cache-Control 可以在请求头或者响应头中设置,并且可以组合使用多种指令

Expires: Wed, 22 Oct 2018 08:41:00 GMT
Cache-control: max-age=30

2:协商缓存:通过设置两种 HTTP Header 实现:Last-Modified 和 ETag(状态码304)

(1)Last-Modified和If-Modified-Since

Last-Modified=>表示本地文件最后修改日期

If-Modified-Since=>会将 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来,否则返回 304 状态码

(2)ETag 和 If-None-Match

ETag=>类似指纹

If-None-Match=>会将当前 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来。并且 ETag 优先级比 Last-Modified 高

三:应用场景

1:频繁变动的资源,需要使用 Cache-Control: no-cache 使浏览器每次都请求服务器,然后配合 ETag 或者 Last-Modified 来验证资源是否有效。虽然不能节省请求数量,但是能显著减少响应数据大小

2:代码文件,可以给代码文件设置缓存有效期一年 Cache-Control: max-age=31536000,只有当 HTML 文件中引入的文件名发生了改变才会去下载最新的代码文件,否则就一直使用缓存

四:图示

五:总结

1:缓存可以减少向服务器请求的的次数,也减少了服务器的压力

2:页面加载速度更快,增加用户体验

六:拓展

1:使用Nginx设置缓存策略

server {
    # html设置成协商缓存或者不缓存
    location ~* \.(html)$ {
        # 关闭访问日志
        access_log off;
        # 进行协商缓存 保证每次调取最新的数据
        add_header  Cache-Control  no-cache;
    }
    
    # 特定文件设置强缓存
    location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ {
        add_header  Cache-Control  max-age=360000; # 默认4天
        #add_header Cache-Control no-store; # 不缓存 但是不推荐 浏览器自带的优化功能用不了了
        #add_header Cache-Control no-cache; # 协商缓存 保证每次调取最新的数据

        # 系统配置文件setting.js,进行协商缓存 保证每次调取最新的数据
        if ($request_filename ~* \.*setting.(js)$) {
            add_header Cache-Control no-cache;
        }
    }   
}

2:改变了内容,缓存不更新(缓存破坏)

是一种通过在内容更改时更改 URL 来使响应在很长一段时间内可缓存的技术。

在部署时,通过url的变化,使重新获取新的资源部署时在文件名中带入Hash值

对于不能加Hash值的资源:比如index.html、setting.js配置文件,使用 Cache-Control: no-cache协商缓存,使浏览器每次都请求服务器,然后配合 ETag 或者 Last-Modified 来验证,获取的是最新的文件