發(fā)現(xiàn)問題
近期vue項目在構(gòu)建完成上線之后,每次往線上更新版本,總會收到一部分反饋——web頁面白屏躏精,需要清除緩存數(shù)據(jù)重新加載才能正常訪問。
問題分析
首先排除掉了publicPath設(shè)置
問題鹦肿,因為大部分用戶能正常訪問到頁面矗烛,無報錯。其次排除首頁加載過慢問題箩溃,因為白屏無論多久都不會渲染頁面高诺。最終定位到緩存問題
,產(chǎn)生原因如下:
在首次上線項目時碾篡,build生成的資源文件直接放到服務(wù)端上線即可。但是當(dāng)?shù)趎(n>1)次上線后筏餐,由于在用戶端會默認(rèn)緩存index.html入口文件开泽,而由于vue打包生成的css/js都是哈希值,跟上次的文件名都不同魁瞪,因此會出現(xiàn)找不到css/js的情況穆律,導(dǎo)致白屏的產(chǎn)生。
優(yōu)化方案
1. meta標(biāo)簽
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Cache" content="no-cache">
2. 時間戳區(qū)分
在項目的配置頁面添加打包配置导俘,根據(jù)vue腳手架不同分以下兩種情況:
- vue-cli@2.x
// webpack.prod.conf.js
const Timestamp = new Date().getTime();
...
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].' + Timestamp + 'js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].' + Timestamp + 'js')
}
- vue-cli@3.x
// vue.config.js
const Timestamp = new Date().getTime();
...
module.exports = {
configureWebpack: config => {
config.output.filename = `js/[name].${Timestamp}.js?t=[hash]`;
config.output.chunkFilename = `js/[id].${Timestamp}.js?t=[hash]`;
},
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 為生產(chǎn)環(huán)境修改配置...
config.plugin('extract-css').tap(args => [{
filename: `css/[name].${Timestamp}.css`,
chunkFilename: `css/[name].${Timestamp}.css`
}])
}
},
}
3. 服務(wù)端配置(nginx)
這個有非常重要峦耘,需要跟服務(wù)端同事溝通,請他們在服務(wù)端配合配置nginx服務(wù)旅薄。
服務(wù)端配置主要解決:
- 設(shè)置
index.html
在用戶端不緩存辅髓,這樣每次拉取的都是線上最新資源; - 設(shè)置
css
和js
文件一定的緩存期少梁,合理利用緩存洛口。
這樣配置的好處是,如果線上資源沒有更新凯沪,我們合理的利用緩存對大體積資源(樣式腳本等)緩存第焰,如果更新了資源,那么index.html
文件則實時更新妨马,用戶端所得到的html文件也是最新資源挺举,樣式及腳本資源都會重新獲取服務(wù)器最新資源緩存到本地。
server {
listen 90;
server_name 22782.s1.natapp.cc;
location / {
root /apps/laikePay/;
try_files $uri $uri/ /index.html;
}
location ^~ /beauty/{
alias /apps/laikeBeauty/;
#以下配置解決html不緩存烘跺,css和js分別緩存7天和30天
if ($request_filename ~* .*\.(?:htm|html)$)
{
add_header Cache-Control "private, no-store, no-cache";
}
if ($request_filename ~* .*\.(?:js|css)$)
{
add_header Cache-Control max-age=604800;
}
if ($request_filename ~* .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$)
{
add_header Cache-Control max-age=2592000;
}
try_files $uri $uri/ /beauty/index.html;
}
location ^~ /beautyThemeChange/{
alias /apps/laikeBeautyThemeChange/;
try_files $uri $uri/ /beautyThemeChange/index.html;
}
location ^~ /retail/{
# alias /apps/laikeRetail/;
# try_files $uri $uri/ /retail/index.html;
proxy_pass http://22782.s1.natapp.cc/beauty/;
}
#location ^~ /merchantPhoneApp/ {
#alias /apps/merchantPhoneApp/;
#try_files $uri $uri/ /merchantPhoneApp/index.html;
#}
}