浏览器缓存是一种存储机制,它可以让 web
应用更快地加载和响应。本文将深入探讨浏览器缓存的工作原理,并提供一些最佳实践来提高 web
应用的性能。
1. 缓存类型
浏览器缓存分为以下几种类型:
- 强缓存
- 协商缓存
2. 强缓存
强缓存是指浏览器在本地磁盘中直接读取并返回资源,而不必向服务器发送任何请求。强缓存通过 HTTP
响应头中的 Expires
和 Cache-Control
实现。
Expires
:指定资源的过期时间,是一个绝对时间。例如,Expires: Thu, 21 Oct 2019 07:28:00 GMT
Cache-Control:可以指定 max-age
值来表示资源的有效期,单位是秒。例如,Cache-Control: max-age=31536000
3. 协商缓存
协商缓存是指浏览器在本地磁盘中找到匹配的资源,但需要向服务器发送一个请求来验证资源是否过期。协商缓存通过 HTTP
响应头中的 Last-Modified
和 ETag
实现。
Last-Modified
:表示资源的最后修改时间。
ETag
:表示资源的唯一标识符。
4. 缓存的工作流程
当浏览器请求一个资源时,会先检查强缓存是否有效。如果有效,则直接从本地磁盘中读取并返回资源。如果强缓存失效,则浏览器会向服务器发送一个请求来验证协商缓存是否有效。
如果协商缓存有效,则服务器返回
304 Not Modified
状态码,并告诉浏览器可以使用本地缓存的资源。如果协商缓存失效,则服务器返回
200 OK
状态码,并返回最新的资源。
5. 最佳实践
- 对于不经常修改的静态资源,可以设置较长的
max-age
值来实现强缓存。
// 借助 express 框架实现强缓存
const express = require('express');
const app = express();
// 设置静态资源最大缓存时长
app.use(express.static('public', {
maxAge: 31536000 // 1年有效期
}));
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
- 对于经常修改的静态资源,可以设置
Cache-Control
:no-cache
或Cache-Control
:max-age=0
来实现协商缓存。
// 借助 Express 框架来实现协商缓存
const express = require('express');
const app = express();
// 禁用强缓存并启用协商缓存
app.use(express.static('public', {
cacheControl: false, // 禁用强缓存
etag: true, // 启用 ETag
lastModified: true // 启用 Last-Modified
}));
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
- 对于动态资源,可以设置
Cache-Control
:no-store
来禁用缓存。
// 借助 Express 框架来禁用对动态资源的缓存
const express = require('express');
const app = express();
// 禁用对 /dynamic-resources 路径下的动态资源的缓存
app.use('/dynamic-resources', (req, res, next) => {
res.setHeader('Cache-Control', 'no-store');
next();
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
- 对于需要身份验证的资源,可以设置
Cache-Control
:private
来防止代理服务器缓存。
// 借助 Express 框架来禁用对需要身份验证的资源的代理服务器缓存
const express = require('express');
const app = express();
// 禁用对 /authenticated-resources 路径下的需要身份验证的资源的代理服务器缓存
app.use('/authenticated-resources', (req, res, next) => {
res.setHeader('Cache-Control', 'private');
next();
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});