前端性能优化可以从多个方面下手,例如加载性能优化、渲染性能优化、代码优化、缓存优化、性能监测和优化等方面下手,下面针对缓存优化分享一下优化思路。
浏览器缓存主要分为强缓存和协商缓存。强缓存命中时,浏览器直接从本地缓存中获取资源,无需向服务器发送请求;协商缓存则在资源过期后,向服务器发送请求询问资源是否有更新,若未更新则使用本地缓存。
一、利用强缓存
1.设置HTTP缓存头
通过设置Cache-Control
和Expires
响应头来控制资源的缓存时间。
Cache-Control
可以设置多种指令,如max-age=31536000
表示资源在 31536000 秒(一年)内有效,可以被缓存。
Expires
指定一个绝对时间,如Expires: Thu, 31 Dec 2024 23:59:59 GMT
,表示在这个时间之前资源可以被缓存。
2.区分静态资源和动态资源
对于静态资源如图片、CSS、JavaScript 文件等,可以设置较长时间的强缓存。因为这些资源一般不会频繁变动,设置长时间缓存可以减少网络请求,提高页面加载速度。
动态资源如根据用户请求生成的页面内容,通常不适合设置强缓存,可以设置较短的缓存时间或者不设置强缓存,以确保用户每次请求都能获取到最新的内容。
二、利用协商缓存
1.设置ETag
和Last-Modified
服务器可以在响应头中设置Last-Modified
,表示资源的最后修改时间。浏览器再次请求资源时,会在请求头中带上If-Modified-Since
,值为上次服务器返回的Last-Modified
时间。服务器对比资源的实际修改时间和这个时间,如果没有变化,则返回 304 状态码,告知浏览器使用本地缓存。
ETag
是服务器生成的资源唯一标识,可以是资源的哈希值等。浏览器请求资源时,在请求头中带上If-None-Match
,值为上次服务器返回的ETag
。服务器对比资源的当前ETag
和请求中的If-None-Match
,如果一致则返回 304 状态码。
2.合理选择ETag
和Last-Modified费
如果资源的修改频率较低且内容不易发生变化,可以优先使用Last-Modified
,因为它的计算成本相对较低。
对于频繁修改但内容变化不大的资源,可以考虑使用ETag
,因为它可以更准确地判断资源是否发生变化。例如,一个文本文件可能经常被修改,但内容的变化可能只是一些小的调整,使用ETag
可以更精确地判断是否需要重新传输资源。
三、Service Worker 缓存
1.注册 Service Worker
Service Worker 是在浏览器后台运行的脚本,可以拦截和处理网络请求,实现离线缓存等功能。
在页面中通过navigator.serviceWorker.register('service-worker.js')
注册 Service Worker 脚本。
2.缓存策略制定
在 Service Worker 脚本中,可以使用caches.open()
打开缓存空间,然后使用cache.addAll()
或fetch()
结合cache.put()
等方法将资源添加到缓存中。
例如,可以在 Service Worker 的install
事件中缓存关键的静态资源:
self.addEventListener('install', event => {
event.waitUntil(
caches.open('my-cache').then(cache => {
return cache.addAll([
'/',
'/index.html',
'/styles.css',
'/script.js'
]);
})
);
});
3.
拦截请求并返回缓存资源
在 Service Worker 的fetch
事件中,可以拦截网络请求,先检查缓存中是否有对应的资源,如果有则直接返回缓存资源,否则发起网络请求并将响应添加到缓存中。
例如:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
if (response) {
return response;
}
return fetch(event.request).then(response => {
const clonedResponse = response.clone();
caches.open('my-cache').then(cache => {
cache.put(event.request, clonedResponse);
});
return response;
});
})
);
});
四、内存缓存与本地存储缓存的结合
1. 内存缓存的运用
对于一些频繁使用且体积较小的资源,可以考虑在内存中进行缓存。例如,使用 JavaScript 的变量或对象来存储一些常用的数据或小型图片的 base64 编码。
优点是访问速度极快,可以在瞬间获取到缓存的数据。但由于内存空间有限,不适合存储大量数据或大型资源。
2.本地存储缓存
localStorage
和sessionStorage
可以用来存储一些数据,以便在页面刷新或重新加载时使用。例如,可以将一些用户设置、表单数据等存储在本地存储中,避免用户重复输入。
但要注意存储的数据量不宜过大,以免影响浏览器性能。同时,要注意数据的安全性和隐私性,避免存储敏感信息。
五、缓存更新策略
1.版本控制
对于静态资源,可以通过在文件名中添加版本号或哈希值来强制浏览器更新缓存。例如,将styles.css
改为styles-v1.2.css
或styles.abc123.css
,当资源内容发生变化时,更新版本号或哈希值,浏览器会认为这是一个新的资源,从而下载新的资源并更新缓存。
2.后台更新缓存
可以在服务器端设置定时任务或通过事件触发,检查资源的变化情况,并更新缓存。例如,当服务器上的静态资源发生变化时,服务器可以自动更新缓存中的资源,以便下次用户请求时能够获取到最新的资源。
3.手动清除缓存
在开发过程中,为了确保能够及时看到最新的代码变化,可以手动清除浏览器缓存。不同浏览器有不同的清除缓存方法,一般可以在浏览器的设置中找到清除缓存的选项。
六、监控与分析缓存效果
1.使用浏览器开发者工具
可以使用浏览器的开发者工具来查看资源的缓存情况,包括强缓存和协商缓存的状态、缓存时间等。在 “Network” 面板中,可以查看每个资源的请求和响应信息,了解资源是否从缓存中获取以及缓存的命中情况。
2.性能监测工具
使用性能监测工具如 Google PageSpeed Insights、WebPageTest 等,可以分析页面的加载性能,包括缓存的使用情况。这些工具会给出具体的优化建议,帮助你进一步优化缓存策略。
3.自定义日志记录
在前端代码中,可以添加自定义的日志记录,记录资源的加载情况、缓存的命中情况等。通过分析这些日志,可以了解缓存的使用效果,发现潜在的问题并进行优化。