压缩分为两种模式
- 动态压缩(压缩工作由express中间件服务器完成,会消耗服务器资源)
- 静态压缩(压缩工作在build的时候就打包好.gz资源,服务器优先返回.gz资源)
一、动态压缩(服务器压缩)
直接借助express的中间件compression即可完成动态压缩
1、安装中间件
npm install compression --save
2、使用中间件压缩
var compression = require('compression');
const app = express()
app.use(compression());
二、静态压缩(构建时就生成.gz资源)
1、安装 compression-webpack-plugin 插件
npm install compression-webpack-plugin
2、webpack配置
...
chainWebpack: function (config: any) {
if (process.env.NODE_ENV === 'production') {
//gzip压缩
config.plugin('compression-webpack-plugin').use(CompressionPlugin, [
{
test: /\.(js|css)$/, //匹配文件名
threshold: 10240, //对超过10k的数据压缩
deleteOriginalAssets: false, //删除源文件
},
]);
}
}
...
3、build后查看构建产物是否存在.gz的资源
4、修改express中间件,请求静态资源时,优先使用gzip文件
// express中间件app.js
// 处理请求静态资源中的gzip文件
app.use(function (req, res, next) {
if (req.originalUrl && req.originalUrl.includes('.') && req.method === 'GET') {
// ps:不要使用compression中间件,compression中间件不会使用已经存在.gz文件,还是会根据请求资源路径去压缩
const fullPath = path.join(__dirname, 'dist', `${req.originalUrl}.gz`);
// 手动检测是否存在同名.gz压缩文件,且浏览器支持gzip 则返回对应的文件
if (fs.existsSync(fullPath) && req.headers['accept-encoding'] && req.headers['accept-encoding'].includes('gzip')) {
logger.info('sendGzipFile-------------------------------:' + fullPath);
// 告诉浏览器用gzip编码格式来解析
res.setHeader('Content-Encoding', 'gzip')
// 此处根据请求路径去设置响应类型,服务器默认根据资源类型设置响应类型,会导致层叠样式表响应类型浏览器无法识别的情况。
if (/\.js$/.test(req.originalUrl)) {
res.setHeader('Content-type', 'application/javascript; charset=UTF-8');
}
if (/\.css$/.test(req.originalUrl)) {
res.setHeader('Content-type', 'text/css; charset=UTF-8');
}
// 并把对应的“.gz”格式文件发送给浏览器。
res.sendFile(fullPath);
}else{
// 没有静态资源对应的.gz文件
next();
}
} else {
// 非静态资源请求
next();
}
});