關於更新發布CSS和JS文件的緩存問題

現現在,瀏覽器大戰下,各個瀏覽器也是拼了命的提升性能,升級JS解析引擎,更好的處理瀏覽器的頁面緩存,讓用戶的瀏覽體驗更快,佔用更小的PC資源。那麼,問題就出如今JS和CSS緩存,甚至頁面緩存上。至於瀏覽器對頁面的緩存,咱們通常經過在服務端發送頁面的時候設置頁面的生存期,通常幾個小時就能緩解很大的服務器壓力,而且,對瀏覽者來說,本地頁面晚更新幾個小時可能問題也不大。但,問題是,若是頁面發生了更新,可是該頁面連接的JS和CSS文件卻被瀏覽器緩存下來,只有待瀏覽器重啓後才能被刪除,甚至有些瀏覽器重啓後也不主動刪除JS和CSS的緩存文件。這樣頁面與JS和CSS文件就可能發生脫節了,從而出現某種異常現象,甚至頁面崩潰。更坑爹的現象是,如今用戶爲了保存本身的工做(娛樂)狀態,根本就長時間不關機,固然也不關閉瀏覽器。從而使得該問題變得更加嚴重。javascript

這裏提供一種簡單而且經常使用的JS和CSS的緩存解決方案。咱們看新浪微博的首頁。css

 

 

新浪微博首頁html

該頁面加載完畢後的頭部代碼以下(使用Fiirbug等Ajax調試工具打開):java

 

新浪微博HTML頭部分代碼程序員

注意上面的每一個JS文件和CSS文件都加上了一個時間戳做爲版本號。瀏覽器

緩存

<script type=」text/javascript」 src=」{JS文件鏈接地址}?version=XXXXXXXX」></script>服務器


<link rel=」stylesheet」 type=」text/css」 href=」{CSS文件鏈接地址}?version=XXXXXXXX」>函數

由於瀏覽器緩存的時候是以URL做爲存儲單位(還記得POST頁面的返回按鈕的問題吧?),工具

從而當每次首頁的文件發生更新的時候只須要更改上面的版本號,就能提醒瀏覽器從新下載該文件了。

 

 

 

 

 


 

 

 

咱們的用戶量大,修改js文件後,用戶反饋登陸出現問題。實際上刷新一下就沒事了。就是由於用戶的瀏覽器使用的仍是本地緩存的js代碼。
 
強制刷新通常就會從新去服務器獲取新的js代碼。但不能讓用戶每次都這樣子去作。
 
 
因而我思考一個問題:

若是修改了js文件中的js代碼,發佈代碼到線上後。用戶的瀏覽器使用的仍是原來js緩存。因此並不會立刻生效。


如何才能讓瀏覽器使用最新的js文件呢?

不少人想到的第一反應是,在<script type="text/javascript" src="/js/common.js" ></script>在後面加一個時間戳來解決。這樣url地址每次變化,瀏覽器就會請求服務端的js,而不會使用緩存。

這樣是解決了。可是會致使瀏覽器每次都要去請求服務端的js文件。佔用帶寬。做爲技術,能不能有種更好的辦法呢?既能避免用戶的瀏覽器每次去請求服務端獲取js文件。又能在發佈新的js代碼後,可以使用最新的js文件?

聽說,在問號後面加版本號,如今不少網站都這麼幹。加個版本號可以解決問題嗎?
 
 
 
加個版本號,js有個版本。若是每次發佈新的js代碼。後面就會附加新的版本號。而後用戶加載html頁面的時候。版本號附加在在
 
<script type="text/javascript" src="/js/common.js?v=99" ></script>
 
若是沒有修改,那麼版本號仍是原來的,這樣作到了:不發佈代碼的時候,瀏覽器使用的是本地緩存。由於版本號沒有變化。
 
如今疑問是,js的版本號如何生成呢?
 
生成一個日期嗎?
 
當天的日期比較好。
 
這樣的確解決了問題。讓用戶可使用。
 
只不過出現一個新的問題來臨了。
 
js文件加上當天的發佈日期做爲版本號便可了。
 
 
有些人針對url後面帶時間戳的作法,會致使瀏覽器每次請求都不會緩存,由於每次請求時間都會變化,url就變化了,因而瀏覽器認爲是一個新的地址了。
 
有人針對這個問題的解決辦法是:這裏URI不是靜態,可能會形成某些瀏覽器不會進行緩存,能夠採用僞靜態配合URL重寫來解決
 
 

 網上查詢資料,縱觀你們的解決思路總結以下:

 

一、修改js的文件名。我以爲這樣很麻煩。形成版本系統的維護困難。不建議。除非是徹底ftp。不過每次發佈都修改文件名稱。的確形成維護的時候很茫然,接手的人看到文件名稱變化,會比較難維護

 

二、路徑後面加時間戳或者隨機數的方式。


 通常都是在html模版中使用一個時間戳或者隨機數函數生成一個值。

<script type="text/javascript" src="{{passport_host}}js/common.js?t={{date("Y-m-d")}}" ></script> 今天和明天的值不一樣了,從新請求服務器。

<script type="text/javascript" src="{{passport_host}}js/common.js?t={{time()}}" ></script> 使用時間戳,每刷新一次html,值都不一樣。隨機數也是同樣的

 

   不推薦使用這種方式。

   由於這樣的方式致使的問題是,每次刷新html,時間戳都是變化的,url就老是惟一的,因而瀏覽器老是去請求服務端獲取js文件,不會使用瀏覽器本地的緩存。佔用帶寬,影響速度

 

 

三、路徑後面加js的版本號。這樣是業界比較成熟的作法。

 

關鍵是這個版本號,怎麼作版本? 難道真的歸入版本系統裏面去?不是的。我忽然靈感來,想到一種程序員本身控制的辦法。

本身主動加時間,若是本次發佈,修改了哪幾個js文件。那麼就在後面加上一個時間點:年月日

若是一天會發布屢次對js文件的修改,那麼程序員還要精確點。年月日時分秒便可。

 

 

 以下:

 

<script type="text/javascript" src="/js/common.js?time=20150518" ></script>

 

我去看了一下淘寶,發現也是這樣一種方式額,不知道對不對?

 

以下:

 

 

 

 

 15年8月12日補充:

 

  公司有好幾千萬註冊會員,因而第三方應用使用咱們網站會員賬號實如今第三方網站登陸,須要設計oauth2.0受權的平臺,因而須要參考微博的oauth體制。

 

  無心中發現他們的css也是使用年月日來控制

 

 

 

進一步思考:

 

這種加時間方法是可行。。不是系統生成的時間,不是全部js文件都加。

 

是否是能夠進一步考慮一種辦法,用程序來進行開關呢?

 

本身勾選。若是這個文件修改了。那麼就設置爲更新。模版中判斷,就根據這個開關,把時間戳自動打上去?

 

不過這樣子以爲不必。由於還沒到那麼重大。其實初期,徹底能夠程序手動把日期打上去便可了。

 

該了什麼js文件,就給哪一個js文件加,這樣已是折衷了。就跟改代碼同樣。代碼都要修改的,這點改也沒多少工做量。

 

 

總結思路:

 

js文件的內容修改了,能夠加個t參數代表一下日期,用這個日期來做爲版本號,看到日期也能知道是哪天發佈的。


沒有修改js文件根本就不用修改日期。

 

 

 

實踐:

         <script type="text/javascript" src="{{passport_host}}js/common.js?t=20150622" ></script>

 

若是下一次修改了這個js文件,那麼發佈的時候,就修改日期

 

<script type="text/javascript" src="{{passport_host}}js/common.js?t=20150628" ></script>

 

沒有修改的js文件,保留原來的值不動便可。

相關文章
相關標籤/搜索