浏览器缓存机制
浏览器的缓存机制,简单的说就是将一次请求的资源保存在本地。客户端和服务端通过http请求约定怎么去使用、更新这个资源。利用这个机制,我们可以减少资源传输,提高页面加载速度。
- Expires 规定了缓存过期时间
- Cache-Control 规定了缓存存活时间
- Last-Modified 该资源最后修改时间
- If-Modified-Since 如果资源在该日期之后发生修改,则进行更新。
- ETag ETag 是代表该文件的唯一字符串,是第二种检查缓存是否需要更新的机制。
- If-None-Match 如果ETag与之不相同则进行更新。
代码分离
单入口只会生成一个打包的bundle.js,它既包括了页面独立的JS文件,也包含了许多从CDN获取的,公用的模块。
哪怕我们对页面的独立JS进行微小改动,bundle.js也需要重新打包。用户再次访问时,就需要下载完整的bundle.js。为了充分使用浏览器的缓存机制,我们需要将公共库单独打包。
CommonsChunkPlugin
单纯的使用多入口,因为所有依赖都要被打包,并不能解决问题。于是需要使用插件CommonsChunkPlugin
修改配置文件webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = function(env) {
return {
entry: {
main: './index.js',
vendor: 'moment'//引入的库
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // 指定公共 bundle 的名字。
})
]
}
}
隐式生成vendor
var webpack = require('webpack');
var path = require('path');
module.exports = function() {
return {
entry: {
main: './index.js'
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// 该配置假定你引入的 vendor 存在于 node_modules 目录中
return module.context && module.context.indexOf('node_modules') !== -1;
}
})
]
};
}
Manifest
Manifest就是webapck runtime code,它支撑页面运行时,webpack可以处理打包后的文件。
当webpack只生成一个bundle时,Manifest这部分代码也被打包进入bundle。而当生成多个bundle时,这部分代码会被放入公共库vendor中。
这就导致vendor文件的hash发生改变。使得浏览器缓存无法生效。
故而,我们需要将Manifest单独独立出来。代码如下
webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = function(env) {
return {
entry: {
main: './index.js',
vendor: 'moment'
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'] // 指定公共 bundle 的名字。
})
]
}
};
隐式
var webpack = require('webpack');
var path = require('path');
module.exports = function() {
return {
entry: {
main: './index.js' //注意这里只有一个入口
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// 该配置假定你引入的 vendor 存在于 node_modules 目录中
return module.context && module.context.indexOf('node_modules') !== -1;
}
}),
//CommonChunksPlugin 将从 vendor和bundles中提取所有的公用库
//但由于已经没有其他公用模块了,故而只会将runtime code存入manifest中
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest'
})
]
};
}