摘要:之離線存儲(chǔ)離線存儲(chǔ)顧名思義,在有線的環(huán)境下先緩存數(shù)據(jù)包括靜態(tài)資源,動(dòng)態(tài)資源,從而在離線環(huán)境下,依舊可以正常使用應(yīng)用單頁(yè)應(yīng)用靜態(tài)資源存儲(chǔ)是一套靜態(tài)資源緩存方案利用該技術(shù)可以實(shí)現(xiàn)配置靜態(tài)資源轉(zhuǎn)發(fā)請(qǐng)求,加快應(yīng)用加載速度,降低服務(wù)器負(fù)載基本用法引入
H5之「離線存儲(chǔ)」
「離線存儲(chǔ)」:顧名思義,在有線的環(huán)境下先緩存數(shù)據(jù)(包括靜態(tài)資源,動(dòng)態(tài)資源),從而在離線環(huán)境下,依舊可以正常使用應(yīng)用(單頁(yè)應(yīng)用)
靜態(tài)資源存儲(chǔ)(ApplicationCache)applicationCache 是一套h5靜態(tài)資源緩存方案.
利用該技術(shù)可以實(shí)現(xiàn)配置靜態(tài)資源/轉(zhuǎn)發(fā)請(qǐng)求,加快應(yīng)用加載速度,降低服務(wù)器負(fù)載.
引入manifest配置文件
... ...
配置manifest文件
CACHE MANIFEST # 修改配置后,附加上下面一段js代碼,才能更新緩存 # 2016972143 # 注釋?zhuān)盒枰彺娴奈募?,無(wú)論在線與否,均從緩存里讀取 CACHE: /dist/0.eda078350ef514670764.bundle.js /dist/common.bundle.js?v=2016972143 /dist/df9f379beae2559b27044dcfdc0653ab.png?v=2016972143 /dist/home.bundle.js?v=2016972143 /dist/home.css?v=2016972143 uncached.js?v=2016972143 #cached.css # 注釋?zhuān)翰痪彺娴奈募?,無(wú)論緩存中存在與否,均從新獲取 NETWORK: * #uncached.js #uncached.css # 注釋?zhuān)韩@取不到資源時(shí)的備選路徑,如index.html訪問(wèn)失敗,則返回404頁(yè)面 FALLBACK: #/v1/team/dirlists mock/team_dirlists.json #/v1/team/app_filelist?isAdd=0&source=team&page=1&pageSize=10&sort=ftime&from=hiwebapp&fid=t293 mock/team_app_filelist.json #index.html 404.html
書(shū)寫(xiě)更新緩沖js
// 每次打開(kāi)頁(yè)面執(zhí)行該代碼段,更新緩存 // !!! 注意:更新緩存后不會(huì)立即生效,需要重新加載頁(yè)面 (function () { var cache = window.applicationCache; cache.addEventListener("updateready", function(e) { if (cache.status == cache.UPDATEREADY) { // Browser downloaded a new app cache. // if (confirm("A new version of this site is available. Load it?")) { cache.swapCache(); window.location.reload(); // } } else { // Manifest didn"t changed. Nothing new to server. } }, false); cache.update() }())
服務(wù)器配置
配置manifest文件,響應(yīng) Content-Type: text/cache-manifest Cache-Control: max-age=0
部署線上代碼時(shí)更新manifest版本號(hào)與配置
按照以上配置,這樣就能實(shí)現(xiàn)靜態(tài)資源緩存
如上圖,from cache的加載時(shí)間相比其他網(wǎng)絡(luò)請(qǐng)求快得多!
其中的fetch/ajax請(qǐng)求不能夠通過(guò)靜態(tài)資源存儲(chǔ),因?yàn)轫憫?yīng)結(jié)果是可能會(huì)變的.
那么對(duì)于異步ajax請(qǐng)求(動(dòng)態(tài)資源)要通過(guò)什么方法才能存儲(chǔ)起來(lái)呢?實(shí)現(xiàn)真正意義的離線存儲(chǔ).
動(dòng)態(tài)資源存儲(chǔ)(WebSQL/IndexedDB)使用前端數(shù)據(jù)庫(kù)可以較為靈活的控制動(dòng)態(tài)資源存儲(chǔ),在這里我使用了indexedDB, 為什么不用WebSQL?
之前做在線聊天應(yīng)用時(shí),使用過(guò)WebSQL存儲(chǔ)聊天記錄
WebSQL已經(jīng)被棄用
WebSQL是傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù),indexedDB是主流的NoSQL DB
基本用法創(chuàng)建一個(gè)通用的數(shù)據(jù)庫(kù)訪問(wèn)接口
var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB; // memCache 內(nèi)存緩沖,避免頻繁的讀寫(xiě)數(shù)據(jù)庫(kù) var req, db, memCache = {}; if(indexedDB) { // version:2 req = indexedDB.open("ajax_cache", 2); // 保證caches成功創(chuàng)建 req.onsuccess = function (e) { db = e.target.result; if(!db.objectStoreNames.contains("caches")){ db.createObjectStore("caches", {keyPath: "id"}); } } // 數(shù)據(jù)庫(kù)版本改變觸發(fā) req.onupgradeneeded=function(e){ var db=e.target.result; if(!db.objectStoreNames.contains("caches")){ db.createObjectStore("caches", {keyPath: "id"}); } console.log("DB version changed to " + db.version); }; req.onerror = function (err) { console.error("indexedDB open failed. ", err) } } export default { isSupported: !!indexedDB, set: (id, data) => { var entity = { id: id, data: data } var transaction = db.transaction("caches", "readwrite"); var store = transaction.objectStore("caches"); var req = store.put(entity); req.onerror = () => { console.error("put data failed. ", entity) } req.onsuccess = () => { memCache[id] = data console.info("put data successed. ", entity) } }, get: (id) => { return new Promise((resolve, reject) => { if(memCache[id]) { resolve(memCache[id]); return; } var transaction = db.transaction("caches", "readwrite"); var store = transaction.objectStore("caches"); var req = store.get(id); req.onerror = () => { console.error("get data failed. ", id) resolve() } req.onsuccess = (e) => { var rlt = e.target.result; console.info("get data successed. ", id, rlt) resolve(rlt && rlt.data) } }) } }
重寫(xiě)fetch/ajax方法
/* reset fetch function for offline be compatible*/ var fetch = require("isomorphic-fetch") import {parse} from "url" var __fetch = fetch; fetch = function (url) { var rlt = parse(url, true); function generateJson(json) { return { json: function () { return json } } } function generateErrorJson() { return generateJson({ errno: 500, errmsg: "你正處于離線狀態(tài)", result: { files: [] } }) } var query = rlt.query; // 去掉時(shí)間戳與重復(fù)的from參數(shù) delete query.t; delete query.from; var id = rlt.pathname var key = MyUtils.jsonToUrl(query) if(MyUtils.isOffline()) { // 離線 if(!id) { return new Promise((resolve, reject) => { resolve(generateErrorJson()) }) } else { if(DB.isSupported) { return DB.get(id).then(json => { return (!json || !json[key]) ? generateErrorJson() : generateJson(json[key]) }) } else { return new Promise((resolve, reject) => { resolve(generateErrorJson()) }) } } } else { return __fetch.apply(null, [].slice.call(arguments)) .then(res => res.json()) .then( (resJson) => { if(DB.isSupported) { var tmp = {}; tmp[key] = resJson; DB.get(id).then(json => { DB.set(id, Object.assign({}, json, tmp)) }) } return generateJson(resJson) } ) } }
可以在chrome的web tool中看到indexedDB
每次請(qǐng)求都緩存下來(lái)了
在脫離網(wǎng)絡(luò)后!依舊可以模擬異步請(qǐng)求!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/61810.html
摘要:本文將從以下幾個(gè)方面闡述架構(gòu)設(shè)計(jì)的一些經(jīng)驗(yàn)和思考。原文及討論請(qǐng)到通訊作為一種跨語(yǔ)言開(kāi)發(fā)模式,通訊層是架構(gòu)首先應(yīng)該考慮和設(shè)計(jì)的,往后所有的邏輯都是基于通訊層展開(kāi)。 關(guān)于Hybrid模式開(kāi)發(fā)app的好處,網(wǎng)絡(luò)上已有很多文章闡述了,這里不展開(kāi)。 本文將從以下幾個(gè)方面闡述Hybrid app架構(gòu)設(shè)計(jì)的一些經(jīng)驗(yàn)和思考。 原文及討論請(qǐng)到 github issue 通訊 作為一種跨語(yǔ)言開(kāi)發(fā)模式,通訊...
摘要:前端面試題總結(jié)持續(xù)更新中為什么只需要寫(xiě)需要來(lái)規(guī)范瀏覽器的行為讓瀏覽器按照它們應(yīng)該的方式來(lái)運(yùn)行基于所以需要對(duì)進(jìn)行引用,才能告知瀏覽器文檔所使用的文檔類(lèi)型。 前端面試題總結(jié)——H5(持續(xù)更新中) 1.HTML5 為什么只需要寫(xiě) ? HTML5 需要doctype來(lái)規(guī)范瀏覽器的行為,讓瀏覽器按照它們應(yīng)該的方式來(lái)運(yùn)行; HTML4.01基于SGML,所以需要對(duì)DTD進(jìn)行引用,才能告知瀏覽器文檔...
閱讀 1845·2021-09-22 15:23
閱讀 3278·2021-09-04 16:45
閱讀 1901·2021-07-29 14:49
閱讀 2779·2019-08-30 15:44
閱讀 1529·2019-08-29 16:36
閱讀 1048·2019-08-29 11:03
閱讀 1520·2019-08-26 13:53
閱讀 516·2019-08-26 11:57