閱讀203 返回首頁    go 阿裏雲 go 技術社區[雲棲]


靜態資源緩存控製grunt插件

前端性能優化中一個很重要的方麵就是充分利用緩存,比如通過cache-control, expires, eTag等來控製靜態資源失效時間,很多大型網站的靜態資源實現實現甚至到了幾年。這確實提高了頁麵加載速度,但同時引來另一個問題,我更改了靜態資源,如何讓客戶端更新緩存。

思路

最有效的解決方案是修改其所有鏈接,這樣,全新的請求將從原始服務器下載最新的內容。

沒錯,但是怎樣更新鏈接?

來看看一般前端團隊的做法

index.html頁麵裏:

<script charset="utf-8" type="text/javascript" src="a.js?t=20131111"></script>

大家會采用添加query的形式修改鏈接。這樣做是比較直觀的解決方案,但在訪問量較大的網站,這麼做可能將麵臨一些新的問題,因為在發布的過程中,index.html和a.js總有一個先後的順序,從而中間出現一段或大或小的時間間隔。對於一個大型互聯網應用來說即使在一個很小的時間間隔內,都有可能出現新用戶訪問。這些用戶訪問到的頁麵和js是不匹配的,會導致頁麵出錯。

這就是為什麼大型web應用在版本上線的過程中經常會較集中的出現前端報錯日誌的原因,也是一些互聯網公司選擇加班到半夜等待訪問低峰期再上線的原因之一。此外,由於靜態資源文件版本更新是“覆蓋式”的,而頁麵需要通過修改query來更新,對於使用CDN緩存的web產品來說,還可能麵臨CDN緩存攻擊的問題。

當版本有更新時,修改所有引用鏈接也是一件與工程管理相悖的事,至少我們需要一個可以“查找-替換”的工具來自動化的解決版本號修改的問題,要知道手動去修改ts是多少讓人崩潰的事情,特別是對於頻繁發布的情況。

針對這個問題,目前最優的解決方案就是基於文件內容的hash版本號,也就是說,將文件內容進行hash,用hash值來代替時間戳。這麼做的好處,文件不變的時候,版本號不變,文件變了,版本號自動更新。

也就是,發布的時候

<script charset="utf-8" type="text/javascript" src="a.js"></script>
自動變成
<script charset="utf-8" type="text/javascript" src="a.js?t=ba9c11c7"></script>
基於以上思路,我寫了個grunt插件,這樣在發布前,輸入命令grunt,文件壓縮,改時間戳神馬的全部自動完成,超讚的有木有!
本來我是打算找找有沒有現成的grunt plugin,但是沒有找到符合我想法的,於是自己動手吧。
點我去看plugin

已發布到npm,npm install asset-cache-control下載

 

問題

上麵的做法,其實還是改靜態資源query值,並沒有解決發布過程中的資源覆蓋先後問題,對於大型網站,做下麵的修改更合適。

<script charset="utf-8" type="text/javascript" src="a_ba9c11c7.js"></script>

下個版本

1. 現在要列出所有需要控製緩存的靜態資源,以後會支持隻列出目錄
2. 對於以前已由時間戳,但不是t=的,要先reset

最後更新:2017-04-03 12:53:57

  上一篇:go Cracking the Coding Interview:: 尋找有環鏈表的環路起始節點
  下一篇:go 獲取Android設備唯一標識碼