ServiceWorker的資源離線與更新html
ServiceWorker是替代Application Cache的機制,目前爲止其兼容性不好。前端
localStorage資源離線緩存與更新算法
基本思路:將JavaScript、CSS資源文件甚至是接口返回的數據資源緩存到瀏覽器的localStorage中,下次打開頁面時不進行JavaScript、CSS資源的請求,而是直接經過localStorage讀取內容,而後插入到頁面中解析執行。瀏覽器
HTML緩存
<div id="versionStore" data-version="2"></div>
JSapp
/** * localStorage方式實現增量更新 */ let localStorage = window.localStorage, oldVersion = localStorage.getItem('version') || 0, // version記錄localStorage中存的版本 newVersion = +document.querySelector('#versionStore').getAttribute('data-version'); // 當前最新版本 let content = null; if(newVersion > oldVersion) { // 內容有更新或第一次加載 const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(event){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ content = xhr.responseText; updateScript(content); // 更新腳本 localStorage.setItem('version', newVersion); // 更新本地版本 localStorage.setItem('a.js', content); // 更新本地內容 } } }; xhr.open("get", "index.js", true); xhr.send(null); } else { // 無內容更新 content = localStorage.getItem('a.js'); // 直接獲取本地內容 updateScript(content) } /** * 更新頁面腳本 * @param content 腳本內容 */ function updateScript(content) { let script = document.createElement('script'); script.innerHTML = content; document.body.appendChild(script); script = null; }
頁面腳本經過獲取頁面上的「最新版本號」和本地localStorage保存的「舊版本號」進行對比。若是本地沒有版本號或者版本號較舊,則加載最新版本的靜態資源文件到頁面上,同時更新本地原有的localStorage緩存的內容和版本號;不然直接讀取localStorage的靜態資源內容到頁面中解析執行。htm
缺點:(1)localStorage的大小限制,同域下通常是5MB;(2)用戶手動清空localStorage會使離線資源失效;(3)讀取localStorage的速度比較慢,尤爲是移動端。blog
基於增量文件的更新方式接口
若是一個文件中只修改了少許字符,上述方式會致使整個資源文件的更新。爲了節省流量咱們須要增量更新。假設咱們已有1.1,1.2,1.3三個版本發佈,如今須要進行1.4的發佈上線。爲了知足增量更新,咱們須要根據前面的三個版本文件內容與最新版本內容進行對比分析,分別生成三個不一樣版本的增量文件1.1-1.4.js,1.2-1.4.js,1.3-1.4.js,同時保留1.4版本的全量文件。ip
// 實現方式跟上述相似,只需修改請求地址 xhr.open("get", `${oldVersion}-${newVersion}.js`, true);
基於文件代碼分塊的增量更新機制
根據大小肯定分割字符數(好比10個字符),文件字符串由幾個字符串塊鏈接組成chunk1-chunk2-chunk3-chunk4,此時須要在chunk1和chunk2之間添加data1,chunk3內容修改成chunk5,chunk4的塊被刪除。
[1, data1, 2, chunk5, -4]
1表示原來chunk1的內容不變,data1表示插入的新內容;-4表示刪除chunk4的文件塊;
let a = 1, b = 1; console.log(a, b); // 修改成 let a = 2, b = 2; console.log(a + b);
基於編輯距離的增量更新機制
上面方式節約資源的量取決於塊的大小和內容變化的塊序號分佈。根據編輯距離算法增量更新的方式能夠真正作到字符級別的更新。它指的是從一個字符串變換到另外一個字符串所須要的最少變化操做步驟。若是能計算獲取兩個文件對比變化時每一個字符的操做步驟,就能夠將操做步驟做爲增量文件下載,而後在瀏覽器端進行代碼的運算更新了。不過這種狀況對於少許的字符更新頗有用,若是一次更新的內容不少,生成的增量文件極可能比源文件還大,因此實際使用過程當中須要結合具體狀況,在上述兩種增量方式中選擇。
有了前端資源的離線和更新機制,就要考慮在每次新資源包發佈後統計新版本的更新覆蓋率。這對於增量更新尤其重要,若是發現某個版本的使用爲0或接近0,該版本就無需在維護。方式有不少中,最簡單的就是上報版本號,每次PV統計時帶上版本號,最後根據PV中的版本號來統計訪問不一樣版本上用戶的分佈狀況。