<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>浏览器的缓存机制 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6/</link><description>Recent content in 浏览器的缓存机制 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 17 Jul 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6/index.xml" rel="self" type="application/rss+xml"/><item><title>浏览器的缓存机制</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/performance/performance-002/</link><pubDate>Tue, 17 Dec 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/performance/performance-002/</guid><description>&lt;h2 id="一前言"&gt;一、前言&lt;/h2&gt;
&lt;p&gt;缓存可以说是性能优化中简单高效的一种优化方式了。一个优秀的缓存策略可以缩短网页请求资源的距离，减少延迟，并且由于缓存文件可以重复利用，还可以减少带宽，降低网络负荷。&lt;/p&gt;
&lt;p&gt;对于一个数据请求来说，可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三步骤中优化性能。比如说直接使用缓存而不发起请求，或者发起了请求但后端存储的数据和前端一致，那么就没有必要再将数据回传回来，这样就减少了响应数据。&lt;/p&gt;
&lt;p&gt;接下来的内容中我们将通过缓存位置、缓存策略以及实际场景应用缓存策略来探讨浏览器缓存机制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如需获取思维导图或想阅读更多优质文章请猛戳&lt;a href="https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fljianshu%2FBlog"&gt;GitHub博客&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/performance/performance-002/image-01.webp"&gt;&lt;/p&gt;
&lt;h2 id="二缓存位置"&gt;二、缓存位置&lt;/h2&gt;
&lt;p&gt;从缓存位置上来说分为四种，并且各自有优先级，当依次查找缓存且都没有命中的时候，才会去请求网络。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Service Worker&lt;/li&gt;
&lt;li&gt;Memory Cache&lt;/li&gt;
&lt;li&gt;Disk Cache&lt;/li&gt;
&lt;li&gt;Push Cache&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="1service-worker"&gt;1.Service Worker&lt;/h3&gt;
&lt;p&gt;Service Worker 是运行在浏览器背后的独立线程，一般可以用来实现缓存功能。使用 Service Worker的话，传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截，所以必须使用 HTTPS 协议来保障安全。&lt;strong&gt;Service Worker 的缓存与浏览器其他内建的缓存机制不同，它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存，并且缓存是持续性的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Service Worker 实现缓存功能一般分为三个步骤：首先需要先注册 Service Worker，然后监听到 install 事件以后就可以缓存需要的文件，那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存，存在缓存的话就可以直接读取缓存文件，否则就去请求数据。&lt;/p&gt;
&lt;p&gt;当 Service Worker 没有命中缓存的时候，我们需要去调用 fetch 函数获取数据。也就是说，如果我们没有在 Service Worker 命中缓存的话，会根据缓存查找优先级去查找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据，浏览器都会显示我们是从 Service Worker 中获取的内容。&lt;/p&gt;
&lt;h3 id="2memory-cache"&gt;2.Memory Cache&lt;/h3&gt;
&lt;p&gt;Memory Cache 也就是内存中的缓存，主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效，可是缓存持续性很短，会随着进程的释放而释放。 &lt;strong&gt;一旦我们关闭 Tab 页面，内存中的缓存也就被释放了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;那么既然内存缓存这么高效，我们是不是能让数据都存放在内存中呢？&lt;/strong&gt; 这是不可能的。计算机中的内存一定比硬盘容量小得多，操作系统需要精打细算内存的使用，所以能让我们使用的内存必然不多。&lt;/p&gt;
&lt;p&gt;当我们访问过页面以后，再次刷新页面，可以发现很多数据都来自于内存缓存&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/performance/performance-002/image-02.webp"&gt;&lt;/p&gt;
&lt;p&gt;内存缓存中有一块重要的缓存资源是preloader相关指令（例如&lt;code&gt;&amp;lt;link rel=&amp;quot;prefetch&amp;quot;&amp;gt;&lt;/code&gt;）下载的资源。总所周知preloader的相关指令已经是页面优化的常见手段之一，它可以一边解析js/css文件，一边网络请求下一个资源。&lt;/p&gt;
&lt;p&gt;需要注意的事情是，&lt;strong&gt;内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值，同时资源的匹配也并非仅仅是对URL做匹配，还可能会对Content-Type，CORS等其他特征做校验&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="3disk-cache"&gt;3.Disk Cache&lt;/h3&gt;
&lt;p&gt;Disk Cache 也就是存储在硬盘中的缓存，读取速度慢点，但是什么都能存储到磁盘中，&lt;strong&gt;比之 Memory Cache 胜在容量和存储时效性上&lt;/strong&gt;。&lt;/p&gt;</description></item></channel></rss>