vue打包優(yōu)化3:hash解決瀏覽器緩存

什么是瀏覽器緩存:

簡單來說,瀏覽器緩存就是把一個已經(jīng)請求過的Web資源(如html頁面,圖片,js,數(shù)據(jù)等)拷貝一份副本儲存在瀏覽器中。緩存會根據(jù)進(jìn)來的請求保存輸出內(nèi)容的副本。當(dāng)下一個請求來到的時候,如果是相同的URL,緩存會根據(jù)緩存機制決定是直接使用副本響應(yīng)訪問請求,還是向源服務(wù)器再次發(fā)送請求。比較常見的就是瀏覽器會緩存訪問過網(wǎng)站的網(wǎng)頁,當(dāng)再次訪問這個URL地址的時候,如果網(wǎng)頁沒有更新,就不會再次下載網(wǎng)頁,而是直接使用本地緩存的網(wǎng)頁。只有當(dāng)網(wǎng)站明確標(biāo)識資源已經(jīng)更新,瀏覽器才會再次下載網(wǎng)頁。

瀏覽器和網(wǎng)站服務(wù)器是如何標(biāo)識網(wǎng)站頁面是否更新的機制?

第一次請求:


image.png

再次請求:


image.png

解決緩存問題的思路

方案一:打包時,給文件名稱后面加hash值,強制瀏覽器重新加載新文件(具體方法見后文)
方案二:在靜態(tài)文件引用時,在路徑后面,增加時間戳或者隨機數(shù)。該方案時對方案1的補充。因為方案1不能解決靜態(tài)資源的問題。比如跟后臺鏈接的ipConfig.js文件放在public路徑下,打包時是直接復(fù)制到dist下的,不會修改文件名稱,不能加hash。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width,initial-scale=1.0" />
        <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
        <script src="<%= BASE_URL %>ipConfig.js?time=<%= new Date().getTime() %>"></script>
        <title>測試頁面</title>
    </head>

    <body>
        <noscript>
            <strong>We're sorry but iods_web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
    </body>
</html>

方案三: Expires、Last-Modified、Etag緩存控制。該方案也是對前兩個方案的補充。該方案主要使用于,在應(yīng)用運行過程中被動態(tài)修改的文件,緩存在瀏覽器,不能重新加載的場景。
具體的修改方法是,在apache的httpd.conf中,

  1. 去掉模塊前的注釋:LoadModule expires_module modules/mod_expires.so
  2. 并在該文件中增加下面代碼
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "modification plus 0 seconds" 
    ExpiresByType image/x-icon A2592000
    ExpiresByType application/x-javascript A2592000
    ExpiresByType text/css A2592000
    ExpiresByType image/gif A604800
    ExpiresByType image/png A604800
    ExpiresByType image/jpeg A604800
    ExpiresByType text/plain A604800
    ExpiresByType application/x-shockwave-flash A604800
    ExpiresByType video/x-flv A604800
    ExpiresByType application/pdf A604800
    ExpiresByType text/html A900
</IfModule>

方案一的具體實現(xiàn):webpack打包時給文件添加hash值:

hash值的添加,有三種:hash,chunkhash,contenthash。用法和區(qū)別如下:

  1. hash
    hash是跟整個項目的構(gòu)建相關(guān),只要項目里有文件更改,整個項目構(gòu)建的hash值都會更改,并且全部文件都共用相同的hash值。代碼如下:


    image.png

2 chunkhash
采用hash計算的話,每一次構(gòu)建后生成的哈希值都不一樣,即使文件內(nèi)容壓根沒有改變。這樣子是沒辦法實現(xiàn)緩存效果,我們需要換另一種哈希值計算方式,即chunkhash。
chunkhash和hash不一樣,它根據(jù)不同的入口文件(Entry)進(jìn)行依賴文件解析、構(gòu)建對應(yīng)的chunk,生成對應(yīng)的哈希值。我們在生產(chǎn)環(huán)境里把一些公共庫和程序入口文件區(qū)分開,單獨打包構(gòu)建,接著我們采用chunkhash的方式生成哈希值,那么只要我們不改動公共庫的代碼,就可以保證其哈希值不會受影響。配置如下:

        output: {
            path: path.resolve(__dirname, 'dist'),
            // filename: '[name].[hash:5].js'
            filename: '[name].[chunkhash].js'
        },

注意下圖,使用chunkhash時,entry有多個入口

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容