摘要:在上一篇,介紹一下漸進(jìn)式離線的文章中,我們討論了典型的應(yīng)該是什么樣子的并且同時(shí)也介紹了。暴露了一個(gè)異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開并且添加如下代碼清除緩存并重新加載。
在上一篇,介紹一下漸進(jìn)式 Web App(離線) - Part 1的文章中,我們討論了典型的pwa應(yīng)該是什么樣子的并且同時(shí)也介紹了 server worker。到目前為止,我們已經(jīng)緩存了應(yīng)用殼。在 index.html和latet.html頁面中,我們的應(yīng)用已經(jīng)實(shí)現(xiàn)了離線加載緩存數(shù)據(jù)。在重復(fù)訪問時(shí),它們的加載速度更快。在本教程第一部分的結(jié)尾,我們能夠離線加載latest.html,但在用戶離線時(shí)無法顯示獲得動(dòng)態(tài)數(shù)據(jù)。這次學(xué)習(xí)我們將:
當(dāng)用戶離線時(shí)候顯示在latest頁面緩存 app的數(shù)據(jù)
利用localStorage去存儲(chǔ) app 的數(shù)據(jù)
當(dāng)用戶連接到Internet時(shí),替換 app 舊的數(shù)據(jù)并獲取更新新的數(shù)據(jù)。
離線存儲(chǔ)在構(gòu)建PWA時(shí),需要考慮各種存儲(chǔ)機(jī)制:
IndexedDB:這是一個(gè)事務(wù)型數(shù)據(jù)庫(kù)系統(tǒng),用于客戶端存儲(chǔ)數(shù)據(jù)。IndexedDB允許您存儲(chǔ)和檢索用鍵索引的對(duì)象,以便對(duì)存儲(chǔ)在其中的數(shù)據(jù)進(jìn)行高性能搜索。IndexedDB暴露了一個(gè)異步API,以避免阻塞DOM的加載。但一些研究表明,在某些情況下,它是阻塞的。使用IndexedDB時(shí)我推薦使用一些第三方庫(kù),因?yàn)樵贘avaScript中操縱它可能非常冗長(zhǎng)復(fù)雜。例如:localForage、idb 和 idb-keyval這些第三方模塊都是很好滴。
indexDB在瀏覽器的兼容性
Cache API:這是存儲(chǔ)URL地址資源的最佳選擇。和Service worker配合是非常好滴。
PouchDB:是CouchDB的開源JavaScript數(shù)據(jù)庫(kù)。它使應(yīng)用程序能夠在本地存儲(chǔ)數(shù)據(jù),離線,然后同步與CouchDB和兼容的服務(wù)器應(yīng)用程序時(shí)重新上線,保持用戶數(shù)據(jù)同步,不管他們下一次在哪里登錄。PouchDB支持所有現(xiàn)代瀏覽器,使用IndexedDB引擎失敗的話就降級(jí)到WebSQL,對(duì)Firefox 29+ (包括 Firefox OS and Firefox for Android), Chrome 30+, Safari 5+, Internet Explorer 10+, Opera 21+, Android 4.0+, iOS 7.1+ 和 Windows Phone 8+等等都是兼容的。
Web Storage 例如 localStorage:它是同步的,是阻止DOM加載的,在瀏覽器中最多使用5MB, 它有簡(jiǎn)單的 api去操作存儲(chǔ)鍵值對(duì)數(shù)據(jù)。
Web Storage 的瀏覽器兼容表
WebSQL:這是瀏覽器的關(guān)系型數(shù)據(jù)庫(kù)解決方案。它是已經(jīng)被廢棄,因此,瀏覽器將來可能不支持它。
根據(jù)PouchDB的維護(hù)者 Nolan Lawson說,在使用數(shù)據(jù)庫(kù)時(shí),最好問自己這些問題:
這個(gè)數(shù)據(jù)庫(kù)是在內(nèi)存中還是在磁盤上?(PouchDB, IndexedDB)?
什么需要存儲(chǔ)在磁盤上?應(yīng)用程序關(guān)閉或崩潰時(shí)應(yīng)該保存哪些數(shù)據(jù)?
需要什么索引才能執(zhí)行快速查詢?我可以使用內(nèi)存索引而不是磁盤的嗎?
我應(yīng)該怎樣構(gòu)造我的內(nèi)存數(shù)據(jù)相對(duì)于我的數(shù)據(jù)庫(kù)數(shù)據(jù)?我在這兩者之間的映射策略是什么?
我的應(yīng)用程序的查詢需求是什么?展現(xiàn)視圖真的需要獲取完整的數(shù)據(jù),還是只需要獲取它所需要的一小部分呢?我可以延遲加載任何東西嗎?
您可以查看考慮如何選擇數(shù)據(jù)庫(kù),以便更全面地了解主題內(nèi)容。
廢話少扯,讓我們實(shí)現(xiàn)即時(shí)加載在我們的 web app 中,我們將用localStorage,由于我在本教程前面強(qiáng)調(diào)的局限性,我建議你不要在生產(chǎn)環(huán)境中使用localStorage。我們正在構(gòu)建的應(yīng)用程序非常簡(jiǎn)單,所以是使用了localStorage。
打開你的js/latest.js文件,我們更新fetchCommits方法去存儲(chǔ)從 Github API 拉取的數(shù)據(jù),存儲(chǔ)在localStorage。代碼如下:
function fetchCommits() { var url = "https://api.github.com/repos/unicodeveloper/resources-i-like/commits"; fetch(url) .then(function(fetchResponse){ return fetchResponse.json(); }) .then(function(response) { console.log("Response from Github", response); var commitData = {}; for (var i = 0; i < posData.length; i++) { commitData[posData[i]] = { message: response[i].commit.message, author: response[i].commit.author.name, time: response[i].commit.author.date, link: response[i].html_url }; } localStorage.setItem("commitData", JSON.stringify(commitData)); for (var i = 0; i < commitContainer.length; i++) { container.querySelector("" + commitContainer[i]).innerHTML = "Message: " + response[i].commit.message + "
" + "Author: " + response[i].commit.author.name + "
" + "Time committed: " + (new Date(response[i].commit.author.date)).toUTCString() + "
" + "" + "Click me to see more!" + "
"; } app.spinner.setAttribute("hidden", true); // hide spinner }) .catch(function (error) { console.error(error); }); };
上面有這段代碼,在第一頁加載的時(shí)候,這些提交的數(shù)據(jù)就存儲(chǔ)到localStorage了,現(xiàn)在我們寫另外一個(gè)函數(shù)去渲染這些localStorage的數(shù)據(jù)。代碼如下:
// Get the commits Data from the Web Storage function fetchCommitsFromLocalStorage(data) { var localData = JSON.parse(data); app.spinner.setAttribute("hidden", true); //hide spinner for (var i = 0; i < commitContainer.length; i++) { container.querySelector("" + commitContainer[i]).innerHTML = "Message: " + localData[posData[i]].message + "
" + "Author: " + localData[posData[i]].author + "
" + "Time committed: " + (new Date(localData[posData[i]].time)).toUTCString() + "
" + "" + "Click me to see more!" + "
"; } };
這段代碼將數(shù)據(jù)從本地存儲(chǔ)并將其渲染 dom 節(jié)點(diǎn)。
現(xiàn)在我們需要知道,什么條件去調(diào)用fetchCommits函數(shù)和fetchCommitsFromLocalStorage函數(shù)。
js/latest.js代碼如下
(function() { "use strict"; var app = { spinner: document.querySelector(".loader") }; var container = document.querySelector(".container"); var commitContainer = [".first", ".second", ".third", ".fourth", ".fifth"]; var posData = ["first", "second", "third", "fourth", "fifth"]; // Check that localStorage is both supported and available function storageAvailable(type) { try { var storage = window[type], x = "__storage_test__"; storage.setItem(x, x); storage.removeItem(x); return true; } catch(e) { return false; } } // Get Commit Data from Github API function fetchCommits() { var url = "https://api.github.com/repos/unicodeveloper/resources-i-like/commits"; fetch(url) .then(function(fetchResponse){ return fetchResponse.json(); }) .then(function(response) { console.log("Response from Github", response); var commitData = {}; for (var i = 0; i < posData.length; i++) { commitData[posData[i]] = { message: response[i].commit.message, author: response[i].commit.author.name, time: response[i].commit.author.date, link: response[i].html_url }; } localStorage.setItem("commitData", JSON.stringify(commitData)); for (var i = 0; i < commitContainer.length; i++) { container.querySelector("" + commitContainer[i]).innerHTML = "Message: " + response[i].commit.message + "
" + "Author: " + response[i].commit.author.name + "
" + "Time committed: " + (new Date(response[i].commit.author.date)).toUTCString() + "
" + "" + "Click me to see more!" + "
"; } app.spinner.setAttribute("hidden", true); // hide spinner }) .catch(function (error) { console.error(error); }); }; // Get the commits Data from the Web Storage function fetchCommitsFromLocalStorage(data) { var localData = JSON.parse(data); app.spinner.setAttribute("hidden", true); //hide spinner for (var i = 0; i < commitContainer.length; i++) { container.querySelector("" + commitContainer[i]).innerHTML = "Message: " + localData[posData[i]].message + "
" + "Author: " + localData[posData[i]].author + "
" + "Time committed: " + (new Date(localData[posData[i]].time)).toUTCString() + "
" + "" + "Click me to see more!" + "
"; } }; if (storageAvailable("localStorage")) { if (localStorage.getItem("commitData") === null) { /* The user is using the app for the first time, or the user has not * saved any commit data, so show the user some fake data. */ fetchCommits(); console.log("Fetch from API"); } else { fetchCommitsFromLocalStorage(localStorage.getItem("commitData")); console.log("Fetch from Local Storage"); } } else { toast("We can"t cache your app data yet.."); } })();
在上面的代碼片斷,我們正在檢查瀏覽器是否支持本地存儲(chǔ),如果它支持,我們繼續(xù)檢查是否已經(jīng)緩存了提交數(shù)據(jù)。如果沒有被緩存,我們將請(qǐng)求數(shù)據(jù),顯示到頁面上并且緩存請(qǐng)求的數(shù)據(jù)。
現(xiàn)在,從新刷新一遍瀏覽器,確保你做了一個(gè)清晰的緩存,強(qiáng)制刷新,否則我們不會(huì)看到我們的代碼更改的結(jié)果。
現(xiàn)在,離線并加載最新頁面。將發(fā)生了什么事呢?
Yaaay!!! 它加載數(shù)據(jù)沒有任何問題。
查看DevTools,你間看到數(shù)據(jù)已經(jīng)被緩存到localStorage
當(dāng)用戶離線時(shí),看看它加載的速度!!!
還有一件事現(xiàn)在,我們可以立即從本地存儲(chǔ)獲取數(shù)據(jù)。但是我們?nèi)绾潍@得最新的數(shù)據(jù)?當(dāng)用戶在線時(shí),我們需要一種仍然獲得新數(shù)據(jù)的方法。
so easy, 讓我們添加一個(gè)刷新按鈕,觸發(fā)一個(gè)請(qǐng)求到GitHub獲得的最新數(shù)據(jù)。
打開latest.html文件,并且添加一個(gè)刷新按鈕到
添加的按鈕后
PWA - Commits
最后,讓我們?cè)诎粹o上附加一個(gè)單擊事件并添加功能。打開js/latest.js并且添加如下代碼:
document.getElementById("butRefresh").addEventListener("click", function() { // Get fresh, updated data from GitHub whenever you are clicked toast("Fetching latest data..."); fetchCommits(); console.log("Getting fresh data!!!"); });
清除緩存并重新加載。現(xiàn)在,你的latest.html頁面看起來應(yīng)該像這樣:
每當(dāng)用戶需要最新數(shù)據(jù)時(shí),他們只需單擊刷新按鈕即可。
附加:
點(diǎn)擊查看下面鏈接
上一篇: 譯介紹一下漸進(jìn)式 Web App(離線) - Part 1
原文地址
項(xiàng)目代碼地址
個(gè)人博客地址
如果有那個(gè)地方翻譯出錯(cuò)或者失誤,請(qǐng)各位大神不吝賜教,小弟感激不盡
期待下一篇: 介紹一下漸進(jìn)式 Web App(消息推送) - Part 3
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/112899.html
摘要:在上一篇,介紹一下漸進(jìn)式離線的文章中,我們討論了典型的應(yīng)該是什么樣子的并且同時(shí)也介紹了。暴露了一個(gè)異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開并且添加如下代碼清除緩存并重新加載。 在上一篇,介紹一下漸進(jìn)式 Web App(離線) - Part 1的文章中,我們討論了典型的pwa應(yīng)該是什么樣子的并且同時(shí)也介紹了 server worker。到目前為止,我們已經(jīng)緩...
摘要:在上一篇,介紹一下漸進(jìn)式離線的文章中,我們討論了典型的應(yīng)該是什么樣子的并且同時(shí)也介紹了。暴露了一個(gè)異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開并且添加如下代碼清除緩存并重新加載。 在上一篇,介紹一下漸進(jìn)式 Web App(離線) - Part 1的文章中,我們討論了典型的pwa應(yīng)該是什么樣子的并且同時(shí)也介紹了 server worker。到目前為止,我們已經(jīng)緩...
摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開,到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開發(fā)多年來有了顯著的發(fā)展。它允許開發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬人服務(wù)。只需一個(gè)瀏覽器,用戶可以輸入U(xiǎn)RL就可以訪問Web應(yīng)用程序了。隨著 Prog...
摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開,到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開發(fā)多年來有了顯著的發(fā)展。它允許開發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬人服務(wù)。只需一個(gè)瀏覽器,用戶可以輸入U(xiǎn)RL就可以訪問Web應(yīng)用程序了。隨著 Prog...
摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開,到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開發(fā)多年來有了顯著的發(fā)展。它允許開發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬人服務(wù)。只需一個(gè)瀏覽器,用戶可以輸入U(xiǎn)RL就可以訪問Web應(yīng)用程序了。隨著 Prog...
閱讀 1712·2021-11-18 10:02
閱讀 2224·2021-11-15 11:38
閱讀 2675·2019-08-30 15:52
閱讀 2199·2019-08-29 14:04
閱讀 3238·2019-08-29 12:29
閱讀 2092·2019-08-26 11:44
閱讀 1000·2019-08-26 10:28
閱讀 839·2019-08-23 18:37