前端頁面緩存技術-ag真人国际官网
a. web前端緩存機制
前端緩存森攜機制有多種,如瀏覽器緩存、cdn緩存、dns緩存、代理伺服器緩存等。
cdn全稱是content delivery network,即內容分發網路。cdn的原理是改世將資源存放在各地的緩存伺服器上,當用戶請求資源時,從就近的伺服器上返回緩存的資源,而不需要每次都從源伺服器獲取,減輕源伺服器的壓力,又能提升用戶的訪問速度。
瀏覽器可以將用戶請求的資源進行緩存,存放在本地。瀏覽器緩存一般通過請求頭來設置。
與瀏覽器緩存有關的頭部有:
瀏覽器會將伺服器的域名與ip地址的映射緩存在本地,這樣用戶在訪問網站時,不用每次都去查詢dns映射表。
在瀏覽器和伺服器之間架設的一個伺服器 ,這個代理伺服器會幫助瀏覽器去請求頁面,然後將頁面進行處理和壓縮(例如壓縮圖片和文件),使頁面變小,再傳輸給瀏覽器。大部分代理伺服器核春肢都有緩存的功能,如果瀏覽器所請求的文件在它本機中存在且是最新的,就不需要再從源伺服器請求數據,提高了瀏覽速度。
在瀏覽某個頁面時,瀏覽器會判斷頁面的關聯內容,進行預載入。用戶在瀏覽a頁面時,就載入好b頁面,這樣當用戶去訪問b頁面時,b頁面很快就出來,提升了用戶體驗。但這個機制有一定的缺陷,就是預判不一定準確,可能會造成流量和資源的浪費。
b. 前端spa應用緩存問題解決與實踐
要解決問題,有先決的理論知識先要了解
分兩種:
這種機制下,瀏覽器會先找本地緩存,命中則不會從伺服器請求,並返回200狀態碼,且附有 disk cache 或者 memory cache 字樣
這種機制,強緩存失效後,瀏覽器會攜帶緩存標識向伺服器發起請求,伺服器根據標識決定是否使用緩存
首先一點,就是 「瀏覽器會攜帶緩存標識」 ,這個標識是什麼,有兩種
好,原理講了,現在凡是用到nginx的,基本上自動都會實現了etag和last-modified,也就是說,這部分實現機制,已經是默認的!不需要你另加處理。
好,問題來了,如何處理前端spa應用的緩存問題呢?
現在的spa要麼vue要麼react要麼angular
默認情況下,我們會看到:
即所有資源第一次進,強緩存,第二次進,無意外情況下,會執行協商緩存。
之所以會出現spa緩存問題,在於index.html是304,那麼客戶端讀取到的,有可能是本地的not modified,那麼繼續下去,讀的依舊是本地的disk cache
如何解決問題呢?
這里有個特性,spa通過webpack打包,一般默認會帶有contenthash值,即當對應文件有改動,這個contenthash值才會改變,進而改變打包出來的文件名,意味著 只有改變了的文件,文件名才會變,沒有改變的文件是不會變的
如果需要對特殊的文件特殊處理,比如文字類型的文件設置更大的緩存時間或者別的,可以參考上述語法單獨加映射
修改後, service nginx reload 一下,瀏覽器可以看到差別:
index.html一直是200,且從伺服器直接讀取,而所有其他的靜態文件,均從memory or disk cache讀取
好,那麼接下來如果有更新,可以想像,變化的文件有
而由於index.html一直是請求伺服器的,那麼得到的入口js也必然是最新的,意味著如果沒改動的,走本地強緩存,有改動的,會請求最新的,之後請求會走本地強緩存。
problem solved.
解決前端spa緩存問題:
c. 前端http請求細節——cache-control(緩存機制)
請求和響應中的 cache-control 指令並不完全相同,具體可以查看 這里 ,包括指令的具體意思,這里不過多贅述。(默認值:private)
瀏覽器的緩存機制是根據 http 報文的緩存標識進行的,瀏覽器第一次向伺服器發起該請求後拿到請求結果,會根據響應報文中 http 頭的緩存標識,決定是否緩存結果。
瀏覽器緩存策略分為兩種:強制緩存和協商緩存。
強制緩存不會向伺服器發送請求,直接從緩存中讀取資源,可以看到請求返回的狀態碼都是200,並且 size 代表該緩存的位置。
瀏覽器讀取緩存的順序為memory –> disk。
三級緩存原理 (訪問緩存優先順序):
在瀏覽器中,瀏覽器會在js,字體,圖片等文件解析執行後直接存入內存緩存中,那麼當刷新頁面時只需直接從內存緩存中讀取(from memory cache);而css文件則會存入硬碟文件中,所以每次渲染頁面都需要從硬碟讀取緩存(from disk cache)。
為什麼css會放在硬碟緩存中?
因為css文件載入一次就可渲染出來,我們不會頻繁讀取它,所以它不適合緩存到內存中,但是js之類的腳本卻隨時可能會執行,如果腳本在磁碟當中,我們在執行腳本的時候需要從磁碟取到內存中來,這樣io開銷就很大了,有可能導致瀏覽器失去響應。
若伺服器的資源最後被修改時間 > if-modified-since的欄位值
則重新返回資源,狀態碼為200;否則則返回304,代表資源無更新,可繼續使用緩存文件
if-none-match 的欄位值 = 該資源在伺服器的etag值
一致則返回304,代表資源無更新,繼續使用緩存文件;不一致則重新返回資源文件,狀態碼為200。
etag 和 last-modified 區別
參考鏈接:
https://juejin.im/entry/5ad86c16f265da505a77dca4
https://www.cnblogs.com/suihang/p/12855345.html
https://www.jianshu.com/p/54cc04190252
d. 【源碼】微前端qiankun源碼閱讀(3):預載入、緩存和通信
【微前端】qiankun源碼閱讀(1):demo與single-spa流程
【微前端】qiankun源慧消碼閱讀(2):載入子應用與沙箱隔離
通過前面的兩篇可以大概了解qiankun的運行,其中可能會有些疑問:一個主應用有多個子應用,如果每次都在切換子應用時才去載入對應子應用的資源,那切換時的體驗會比較差。為此,qiankun提供了預載入功能,可以看到在start中調用了 doprefetchstrategy :
去到 src/prefetch.ts 中查看 doprefetchstrategy ,可以看到其默認預載入策略是 prefetchafterfirstmounted ,也就是等當前子應用加巧數載完畢後,再去預載入其他子應用。 prefetchafterfirstmounted 很簡單,就是在 requestidlecallback 中調用我們之前講到的 importentry 去載入每個子應用。
requestidlecallback 是一個相對新的api,可以用它來執行一些低優先順序的任務,它會在瀏覽器空閑的時候才去執行,從而避免影響當前子應用的載入。
另外有個問題是,如果我們每次切換應用都去 importentry 重新載入資源,前寬知那不好。可以將資源保存起來。
這里其實也是 importentry 做好了, importentry 會將請求到的資源保存在 embedhtmlcache 變數中。
qiankun中的通信很簡單,在 initglobalstate api文檔 可以查看其使用。
這里源碼在 src/globalstate.ts 中。各種通信方式在微前端框架里同樣適用,沒啥好看。
qiankun框架的源碼閱讀暫時先這樣,希望以後有應用場景可以使用一下這個框架。
e. 能用js或者前端的什麼方法實現清除瀏覽器緩存嗎
可以用js實現清除瀏覽器緩存,解決方法如下:
1、在靜態頁面也就是以.html,.jsp,.aspx,.php結尾的文件中在
注意事項:
javascriptjavascript基於對象和事件驅動並具有相對安全性的客戶端腳本語言。也是一種廣泛用於客戶端web開發的腳本語言,常用來給html網頁添加動態功能,比如響應用戶的各種操作。