前端瀏覽器緩存及代碼部署
今天主要談談前端性能優化之瀏覽器緩存。
前言
最近手上剛剛拆掉石膏,去樓下房友幫忙。樓下房友領導來自阿里,前端用的是阿里的ant-design,設計將設計圖上傳到藍湖,聊天工具也採用阿里的釘釘。有時間我也多多去樓下房友交流學習,多交流,就會有提升。最近也比較忙,好久沒有更新博客了。閑言少敘,今天主要談談前端性能優化之瀏覽器緩存。
瀏覽器緩存
我前面寫過瀏覽器緩存的文章,也寫過html5離線緩存,關於這些緩存,我們很容易搞不清,例如:200 OK (FROM MemoryCache、FROM DiskCache) 及 304 NOT MODIFIED 還有 application cache (離線緩存)等等。
200 from memory cache 不訪問伺服器,直接讀緩存,從內存中讀取緩存。此時的數據時緩存到內存中的,當kill進程後,也就是瀏覽器關閉以後,數據將不存在。但是這種方式只能緩存派生資源
200 from disk cache 不訪問伺服器,直接讀緩存,從磁碟中讀取緩存,當kill進程時,數據還是存在。這種方式也只能緩存派生資源
304 Not Modified 訪問伺服器,發現數據沒有更新,伺服器返回此狀態碼。然後從緩存中讀取數據。
三級緩存原理
先去內存看,如果有,直接載入
如果內存沒有,擇取硬碟獲取,如果有直接載入如果硬碟也沒有,那麼就進行網路請求載入到的資源緩存到硬碟和內存
一般瀏覽圖片,如下流程:
訪問-> 200 -> 退出瀏覽器
再進來-> 200(from disk cache) -> 刷新 -> 200(from memory cache)
application cache和上面緩存有點區別,是離線緩存,就是資源可以從硬碟上讀取而不用聯網,即使斷網,用戶也可以瀏覽。
設置瀏覽器緩存
304是協商緩存還是要和伺服器通信一次,要想斷絕伺服器通信,就要強制瀏覽器使用本地緩存(cache-control/expires),
一般有如下幾種方式設置瀏覽器緩存。
1、通過HTTP的META設置expires和cache-control
http-equiv="Cache-Control" content="max-age=7200" />http-equiv="Expires" content="Sun Oct 15 2017 20:39:53 GMT+0800 (CST)" />
這樣寫的話僅對該網頁有效,對網頁中的圖片或其他請求無效。
2、apache伺服器配置圖片,css,js,flash的緩存
這個主要通過伺服器的配置來實現這個技術,如果使用apache伺服器的話,可以使用mod_expires模塊來實現:
編譯mod_expires模塊:
Cd /root/httpd-2.2.3/modules/metadata/usr/local/apache/bin/apxs -i -a -c mod_expires.c //編譯
先打開httpd.conf文件,然後查找expires這個模塊,找到後,刪除左邊的#號,表示打這個模塊,並重啟apache伺服器
編輯httpd.conf配置:添加下面內容
mod_expires.c>ExpiresActive onExpiresDefault "access plus 1 month"ExpiresByType text/html "access plus 1 months"ExpiresByType text/css "access plus 1 months"ExpiresByType image/gif "access plus 1 months"ExpiresByType image/jpeg "access plus 1 months"ExpiresByType image/jpg "access plus 1 months"ExpiresByType image/png "access plus 1 months"EXpiresByType application/x-shockwave-flash "access plus 1 months"EXpiresByType application/x-javascript "access plus 1 months"#ExpiresByType video/x-flv "access plus 1 months"
3、php等設置
php header("Cache-Control: public"); header("Pragma: cache"); $offset = 30*60*60*24; // cache 1 month $ExpStr = "Expires: ".gmdate("D, d M Y H:i:s", time() + $offset)." GMT"; header($ExpStr);?>
或者
$seconds_to_cache = 3600;$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";header("Expires: $ts"); header("Pragma: cache");header("Cache-Control: max-age=$seconds_to_cache");
緩存情況下前端代碼部署
問題一:有了緩存,如何進行前端代碼更新呢?
我們可以在資源文件或者圖片後面添加版本號,如下圖。
問題二:但是所有文件都加了版本號之後,我們只更改了一個文件,其他文件的緩存不是浪費了嗎?
解決這個問題,我們可以用 數據摘要要演算法,對文件求摘要信息,摘要信息與文件內容一一對應。如下圖:
這樣就解決了這個問題。
問題三:新的問題又來了,文件發布怎麼辦?
1、先部署頁面,再部署資源:在二者部署的時間間隔內,如果有用戶訪問頁面,就會在新的頁面結構中載入舊的資源,並且把這箇舊版本的資源當做新版本緩存起來,其結果就是:用戶訪問到了一個樣式錯亂的頁面,除非手動刷新,否則在資源緩存過期之前,頁面會一直執行錯誤。
2、先部署資源,再部署頁面:在部署時間間隔之內,有舊版本資源本地緩存的用戶訪問網站,由於請求的頁面是舊版本的,資源引用沒有改變,瀏覽器將直接使用本地緩存,這種情況下頁面展現正常;但沒有本地緩存或者緩存過期的用戶訪問網站,就會出現舊版本頁面載入新版本資源的情況,導致頁面執行錯誤,但當頁面完成部署,這部分用戶再次訪問頁面又會恢復正常了。好的,上面一坨分析想說的就是:先部署誰都不成!都會導致部署過程中發生頁面錯亂的問題。所以,訪問量不大的項目,可以讓研發同學苦逼一把,等到半夜偷偷上線,先上靜態資源,再部署頁面,看起來問題少一些。
如何解決這些問題呢?
這個問題,起源於資源的 覆蓋式發布,用 待發布資源 覆蓋 已發布資源,就有這種問題。解決它也好辦,就是實現 非覆蓋式發布,如下圖:
看上圖,用文件的摘要信息來對資源文件進行重命名,把摘要信息放到資源文件發布路徑中,這樣,內容有修改的資源就變成了一個新的文件發布到線上,不會覆蓋已有的資源文件。上線過程中,先全量部署靜態資源,再灰度部署頁面,整個問題就比較完美的解決了。
總結如下:
1、 配置超長時間的本地緩存 —— 節省帶寬,提高性能
2、採用內容摘要作為緩存更新依據 —— 精確的緩存控制3、 靜態資源CDN部署 —— 優化網路請求4、更資源發布路徑實現非覆蓋式發布 —— 平滑升級
原作者: haorooms 來自: haorooms
原文鏈接:前端瀏覽器緩存及代碼部署
推薦閱讀: