前端缓存分为强缓存和协商缓存两种。篇够 强缓存主要使用Expires、彻底Cache-Control 两个头字段,弄懂两者同时存在Cache-Control 优先级更高。前端当命中强缓存的缓存时候,客户端不会再求,篇够直接从缓存中读取内容,彻底并返回HTTP状态码200。弄懂 响应头,前端代表该资源的缓存过期时间。是篇够一个GMT 格式的标准时间。 当客户端请求服务器的彻底时候,服务器会返回资源的弄懂同时还会带上响应头Expires,表示资源的前端过期具体时间,如果客户端在过期时间之前再次获取该资源,缓存就不需要再请求我服务器了,可以直接在缓存里面拿。 使用Expires强缓存优点: 使用Expires强缓存缺点 请求/响应头,缓存控制字段,精确控制缓存策略。 为了让强缓存更精确,HTTP1.1增加了Cache-Control字段。Cache-Control既能出现在请求头又能出现在响应头,其不同的值代表不同的意思,下面我们具体分析一下。 Cache-Control 服务端参数: Cache-Control 客户端参数: 协商缓存主要有四个头字段,它们两两组合配合使用,If-Modified-Since 和 Last-Modified一组,Etag 和 If-None-Match一组,当同时存在的时候会以Etag 和 If-None-Match为主。当命中协商缓存的时候,服务器会返回HTTP状态码304,香港云服务器让客户端直接从本地缓存里面读取文件。 请求头,资源最近修改时间,由浏览器告诉服务器。其实就是第一次访问服务端返回的Last-Modified的值。 响应头,资源最近修改时间,由服务器告诉浏览器。 响应头,资源标识,由服务器告诉浏览器。 请求头,缓存资源标识,由浏览器告诉服务器。其实就是第一次访问服务端返回的Etag的值。 当客户端第一次请求服务器的时候,服务端会返回一个Last-Modified响应头,该字段是一个标准时间。客户端请求服务器的时候会带上If-Modified-Since请求头字段,该字段的值就是服务器返回的Last-Modified的值。服务器接收到请求后会比较这两个值是否一样,一样就返回304,让客户端从缓存中读取,不一样就会返回新文件给客户端并更新Last-Modified响应头字段的值。 使用If-Modified-Since 和 Last-Modified的优点: 使用If-Modified-Since 和 Last-Modified的缺点: 为了解决文件修改时间只能精确到秒带来的问题,我们引入 Etag 响应头。Etag 是由文件修改时间与文件大小计算而成,只有当文件文件内容或修改时间变了Etag的值才会发生变化。 当客户端第一次请求服务器的时候,服务端会返回一个Etag响应头。客户端请求服务器的时候会带上If-None-Match请求头字段,该字段的值就是服务器返回的Etag的值。服务器接收到请求后会比较这两个值是否一样,一样就返回304,让客户端从缓存中读取,不一样就会返回新文件给客户端并更新Etag响应头字段的值。 使用Etag 和 If-None-Match的优点: 引入了缓存固然是好事,能大大提升响应速度以及减轻服务端的压力,但是也会出现一些问题,比如我们明明更新了系统版本,为什么客户端看到的还是老文件。在不同的时代有不同的解决方案。 老方案通过人工自己修改文件名或者在文件名后带上版本号、时间戳,这样客户端就会当新文件请求并使用,之前的强缓存就算在有效期内也会失效。 复制代码 在现在的构建阶段基本上都不需要人工操作了,都是使用构建工具比如Wbpack、Gulp、Grunt等构建工具自动构建。比如在使用Webpack构建的时候,会根据文件名或文件内容自动计算hash值来给文件命名,当内容或文件名发生改变的时候,构建出来的文件名也一定会不一样,这样也解决了强缓存还在有效期内的问题。 pragma是旧产物,已经逐步抛弃,有些网站为了向下兼容还保留了这个字段。pragma的值为no-cache时,表示禁用缓存。优先级是 pragma > cache-control > expires。 有了这张流程图,可以让你们理解的更清楚。 如果我们使用Nginx作为Web服务器,我们可以如下配置。 location / { # 其它配置 ... if ($request_uri ~* .*[.](js|css|map|jpg|png|svg|ico)$) { #非html缓存1个月 add_header Cache-Control "public, max-age=2592000"; } if ($request_filename ~* ^.*[.](html|htm)$) { #html文件使用协商缓存 add_header Cache-Control "public, no-cache"; } } 复制代码 很多小伙伴会好奇,这缓存到底存在哪里了呢?别急,我们接着往下讲。 按缓存位置分类我们可以分为memory cache、disk cache、Service Worker三类,我们可以在 Chrome 的开发者工具中,Network -> Size 一列看到一个请求最终的处理方式:如果是大小 (多少 K, 多少 M 等) 就表示是网络请求,否则会列出 from memory cache、from disk cache、from ServiceWorker就表示命中了缓存。 微信截图_20220119110918.png 微信截图_20220119110855.png 本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个赞~~分类
强缓存
协商缓存
扩展
缓存失效问题
pragma
流程图
缓存的配置
缓存到底存在哪?
后记