瀏覽器緩存機(jī)制
瀏覽器的緩存機(jī)制,簡(jiǎn)單的說(shuō)就是將一次請(qǐng)求的資源保存在本地缚柳。客戶端和服務(wù)端通過(guò)http請(qǐng)求約定怎么去使用敛纲、更新這個(gè)資源喂击。利用這個(gè)機(jī)制,我們可以減少資源傳輸淤翔,提高頁(yè)面加載速度翰绊。
- Expires 規(guī)定了緩存過(guò)期時(shí)間
- Cache-Control 規(guī)定了緩存存活時(shí)間
- Last-Modified 該資源最后修改時(shí)間
- If-Modified-Since 如果資源在該日期之后發(fā)生修改,則進(jìn)行更新旁壮。
- ETag ETag 是代表該文件的唯一字符串监嗜,是第二種檢查緩存是否需要更新的機(jī)制。
- If-None-Match 如果ETag與之不相同則進(jìn)行更新抡谐。
代碼分離
單入口只會(huì)生成一個(gè)打包的bundle.js裁奇,它既包括了頁(yè)面獨(dú)立的JS文件,也包含了許多從CDN獲取的麦撵,公用的模塊刽肠。
哪怕我們對(duì)頁(yè)面的獨(dú)立JS進(jìn)行微小改動(dòng)溃肪,bundle.js也需要重新打包。用戶再次訪問(wèn)時(shí)音五,就需要下載完整的bundle.js惫撰。為了充分使用瀏覽器的緩存機(jī)制,我們需要將公共庫(kù)單獨(dú)打包躺涝。
CommonsChunkPlugin
單純的使用多入口厨钻,因?yàn)樗幸蕾嚩家淮虬⒉荒芙鉀Q問(wèn)題坚嗜。于是需要使用插件CommonsChunkPlugin
修改配置文件webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = function(env) {
return {
entry: {
main: './index.js',
vendor: 'moment'//引入的庫(kù)
},
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,它支撐頁(yè)面運(yùn)行時(shí)苍蔬,webpack可以處理打包后的文件诱建。
當(dāng)webpack只生成一個(gè)bundle時(shí),Manifest這部分代碼也被打包進(jìn)入bundle银室。而當(dāng)生成多個(gè)bundle時(shí)涂佃,這部分代碼會(huì)被放入公共庫(kù)vendor中。
這就導(dǎo)致vendor文件的hash發(fā)生改變蜈敢。使得瀏覽器緩存無(wú)法生效辜荠。
故而,我們需要將Manifest單獨(dú)獨(dú)立出來(lái)抓狭。代碼如下
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' //注意這里只有一個(gè)入口
},
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中提取所有的公用庫(kù)
//但由于已經(jīng)沒(méi)有其他公用模塊了,故而只會(huì)將runtime code存入manifest中
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest'
})
]
};
}