前端缓存分为HTTP缓存和浏览器缓存
这里主要笔记http缓存
先说总结的内容
webpack配置(主要是文件名上有个hash值,便于服务器校验文件有没有修改)
使用hash的好处就是,使版本发布之后,使之前文件的强缓存失效
module.exports = {
output: {
filename: 'bundle.[contenthash].js',
path: path.resolve(__dirname, 'dist'),
},
};
nginx配置 (主要是配置html文件不强缓存,别的文件使用强缓存+协商缓存)
location / {
root www; # 访问根目录
index index.html index.htm; # 入口文件
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
# 启用强缓存的静态资源, 强缓存过期之后使用协商缓存
expires 7d; # 设置缓存时间为7天
if_modified_since before;
add_header Cache-Control "max-age=604800, public"; # 设置强缓存
}
location ~* \.html$ {
# 不启用强缓存的 HTML 文件
expires off;
}
总之,虽然强缓存是首选的缓存策略,但协商缓存仍然可以提供额外的性能优势,并减少不必要的网络请求,对于代理前端静态资源的Nginx配置仍然有用。
就是设置时间,时间不到就强制一直取本地的,设置了之后就不用跟服务器协商了
Expires 和 Chache-control 都是标识时间的字段,需要注意的是如果二者同时出现,Chache-control 的优先级是高于 Expires 。
但 Expires 是 HTTP1.0 的规范,时间格式是 GTM 字符串,如如果服务器时间和客户端时间差别较大时,会导致内存混乱。而服务器的时间和用户实际时间不正常是很正常的现象,所以在使用 Expires 的时候会出现一些问题,建议还是使用 Chache-control 来标识时间
Cache-Control 这个字段是 http 1.1 的规范,一般常用该字段的 max-age 值来进行判断,它是一个相对时间所以比较准确
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
assetModuleFilename: '[name][contenthash][ext]',
},
};
这个配置使用了 [contenthash] 来生成文件名,这意味着如果文件内容没有改变,contenthash 也不会改变,从而利用浏览器的强缓存
location /static/ {
alias /path/to/static/files;
expires 30d; # 设置缓存时间为30天
}
const express = require('express');
const app = express();
app.use('/static', express.static('public', {
maxAge: '30d', // 设置缓存时间为30天
}));
发请求到服务器,由服务器判断标签的值是不是最新的,是最新的就不返回内容,否则就返回内容
协商缓存是由服务器来决定,这个资源到底是否更新。整个过程也是涉及到两个字段。在第一次请求的 header 中会出现 Last-Modified 或是 Etag,注意是第一次请求的时候就会有,因为要通过这个字段来判断资源是否可用。
如果是 Etag 对应的是 if-None-Match 字段,是一段唯一标识符,告诉服务器本地缓存文件的最后修改时间。
如果是 Last-Modified 对应的是 if-Modified-Since 字段,是一段时间格式的字符串,比如是哈希值,服务端判断哈希是否一致。HTTP中并没有指定如何生成 ETag,这个由开发者自行决定。
以上两种,如果服务端判断一样,则返回 304 Not Modified,如果不一致则返回新的资源,并且更新本地缓存
module.exports = {
output: {
filename: 'bundle.[contenthash].js',
path: path.resolve(__dirname, 'dist'),
},
};
location /static/ {
alias /path/to/static/files;
if_modified_since exact;
add_header ETag "your_etag_value";
}
const express = require('express');
const app = express();
app.use('/static', express.static('public', {
etag: 'your_etag_value',
lastModified: true,
}));