静态资源
静态资源指的是不需要经过服务端处理的文件,通常是一些图片、音频、字体、视频、CSS、JavaScript 等类型的文件。这类文件相对于动态资源来说,内容不会根据每次请求的情况而改变,因此服务器可以直接返回文件给客户端,无需进行逻辑计算。
在前端开发中,静态资源是构建 Web 项目的重要组成部分。通过合理的处理和优化静态资源,可以提高网站性能和用户体验,减少服务器压力。
动态资源
动态资源指的是在请求时动态生成的内容,而不是静态的可直接访问的文件。这通常包括使用服务器端代码(如PHP或Python)从数据库中检索数据或执行其他操作,以便根据用户请求创建动态HTML页面。常见的动态资源包括:动态网页、API响应、在线游戏、实时聊天等。在web开发中,动态资源可以通过服务器端编程语言提供,如PHP、Python、Ruby等。
单页面应用中缓存策略
单页面应用中,我们会使用不同的打包工具,打包工具通常会对产出的css,js文件进行hash命名,每一次构建都是一个新的名称。浏览器检测到资源名称或 URL 发生变化,会重新请求资源,而不会使用缓存。这是程序员每次修改代码发布的时候需要强制更新静态资源的策略。而程序员没有代码更新的时候,用户第二次访问当前页面的时候就会触发HTTP缓存策略(网上一堆文章就不贴了,注意我们现在使用的HTTP1.1)。这个时候我们的缓存策略应该怎么设置呢?
在单页面应用中,对于静态资源,通常的缓存策略:强缓存和协商缓存同时设置,单纯的设置强缓存,一旦过期无法及时获取到最新资源,只使用协商缓存会增加服务器的负担。
如果不显示设置缓存策略,默认是什么规则呢?
如果在HTTP 1.1中未设置Cache-Control或其他缓存控制标头,则会默认使用以下值:
1.对于请求标头(request headers):Pragma: no-cache
2.对于响应标头(response headers):Cache-Control: private, max-age=0, no-cache。
这意味着对于每个请求,浏览器都将向服务器发送一个条件请求以检查资源是否已更改,并根据需求从源服务器重新下载资源。这可能会导致更多的网络流量和较慢的页面加载时间。为了解决这个问题,通常需要显式地设置适当的缓存策略来减少不必要的网络流量和提高网站性能。
HTTP缓存策略是前端设置还是后端设置?
HTTP缓存策略可以在前端和后端同时进行设置。
前端可以通过设置 HTTP 响应头来控制浏览器缓存的行为,常见的设置包括:
Cache-Control
:用于指定缓存控制策略,可以设置max-age、no-cache、no-store、public、private
等属性,具体含义可以参考 HTTP 协议规范。Expires
:用于指定缓存过期时间,是一个 GMT 格式的时间字符串。Last-Modified
和ETag
:用于实现协商缓存机制,分别表示资源的最后修改时间和唯一标识符。
后端也可以通过设置 HTTP 响应头来控制缓存的行为,一般使用类似于前端的 Cache-Control、Expires、Last-Modified 和 ETag 等属性。后端还可以根据请求的参数或者路径等信息动态生成响应头,实现更加灵活的缓存策略。
对动态资源设置缓存策略
前端通常只是通过api接口(动态资源)可以设置请求头。比如:
const axios = require('axios');
// 发送 GET 请求,并进行缓存配置
axios.get('/api/data', {
headers: {
// 强制每隔 10 秒向服务器发送一次请求
'Cache-Control': 'max-age=10'
},
validateStatus: function (status) {
return status >= 200 && status < 400; // 只有返回状态码在 200 到 399 之间的请求才会被缓存
}
}).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.log(error);
});
// 发送带缓存验证信息的 GET 请求
axios.get('/api/data', {
headers: {
// 将服务器发送的 Last-Modified 字段保存到客户端
'If-Modified-Since': localStorage.getItem('last-modified'),
// 将服务器发送的 ETag 字段保存到客户端
'If-None-Match': localStorage.getItem('etag')
},
validateStatus: function (status) {
return status >= 200 && status < 400; // 只有返回状态码在 200 到 399 之间的请求才进行缓存验证
}
}).then(function (response) {
if (response.status === 304) { // 如果服务器返回 304 状态码,则使用本地缓存
console.log('从缓存中读取数据');
console.log(localStorage.getItem('data'));
} else { // 否则返回新的数据,并更新缓存验证信息
console.log('从服务器获取数据');
console.log(response.data);
localStorage.setItem('last-modified', response.headers['last-modified']);
localStorage.setItem('etag', response.headers['etag']);
localStorage.setItem('data', response.data);
}
}).catch(function (error) {
console.log(error);
});
对静态资源设置缓存策略
静态资源设置HTTP缓存的代码通常写在服务器端,具体位置会根据服务器软件不同而有所差异。如果是使用 Node.js 构建的 Web 应用程序,你可以在服务器中使用 Express 框架来进行配置。一般来说,你需要使用 express.static 函数指定静态资源目录,并在其中设置相应的缓存控制头信息。以下是一个使用 Express 设置 HTTP 缓存的示例:
const axios = require('axios');
// 发送 GET 请求,并进行缓存配置
axios.get('/api/data', {
headers: {
// 强制每隔 10 秒向服务器发送一次请求
'Cache-Control': 'max-age=10'
},
validateStatus: function (status) {
return status >= 200 && status < 400; // 只有返回状态码在 200 到 399 之间的请求才会被缓存
}
}).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.log(error);
});
// 发送带缓存验证信息的 GET 请求
axios.get('/api/data', {
headers: {
// 将服务器发送的 Last-Modified 字段保存到客户端
'If-Modified-Since': localStorage.getItem('last-modified'),
// 将服务器发送的 ETag 字段保存到客户端
'If-None-Match': localStorage.getItem('etag')
},
validateStatus: function (status) {
return status >= 200 && status < 400; // 只有返回状态码在 200 到 399 之间的请求才进行缓存验证
}
}).then(function (response) {
if (response.status === 304) { // 如果服务器返回 304 状态码,则使用本地缓存
console.log('从缓存中读取数据');
console.log(localStorage.getItem('data'));
} else { // 否则返回新的数据,并更新缓存验证信息
console.log('从服务器获取数据');
console.log(response.data);
localStorage.setItem('last-modified', response.headers['last-modified']);
localStorage.setItem('etag', response.headers['etag']);
localStorage.setItem('data', response.data);
}
}).catch(function (error) {
console.log(error);
});
Next.js中如何设置headers呢
在Next.js中,可以使用next.config.js文件来进行HTTP缓存策略的配置。具体步骤如下:
- 在根目录下创建一个名为next.config.js的文件。
- 在该文件中,创建一个对象并导出该对象。对象中包含了一个函数async headers() {},用于设置HTTP响应头。
- 在函数headers()中,使用setHeader()方法设置静态资源的缓存控制相关的HTTP响应头。例如,可以设置Cache-Control和Expires响应头。
module.exports = {
async headers() {
return [
{
source: '/about',
headers: [
{
key: 'x-custom-header',
value: 'my custom header value',
},
{
key: 'x-another-custom-header',
value: 'my other custom header value',
},
],
},
]
},
}
Service Worker 缓存
Service Worker 可以拦截网络请求并将响应缓存至浏览器的本地存储,当再次请求相同 URL 时则直接从本地缓存中获取数据。
CDN 缓存
通过使用全球分布式 CDN 服务,可以让用户从离自己最近的节点下载资源,同时也可以利用 CDN 的缓存机制来加速加载速度。