摘要:在上一篇,介紹一下漸進式離線的文章中,我們討論了典型的應該是什么樣子的并且同時也介紹了。暴露了一個異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開并且添加如下代碼清除緩存并重新加載。
在上一篇,介紹一下漸進式 Web App(離線) - Part 1的文章中,我們討論了典型的pwa應該是什么樣子的并且同時也介紹了 server worker。到目前為止,我們已經緩存了應用殼。在 index.html和latet.html頁面中,我們的應用已經實現了離線加載緩存數據。在重復訪問時,它們的加載速度更快。在本教程第一部分的結尾,我們能夠離線加載latest.html,但在用戶離線時無法顯示獲得動態數據。這次學習我們將:
當用戶離線時候顯示在latest頁面緩存 app的數據
利用localStorage去存儲 app 的數據
當用戶連接到Internet時,替換 app 舊的數據并獲取更新新的數據。
離線存儲在構建PWA時,需要考慮各種存儲機制:
IndexedDB:這是一個事務型數據庫系統,用于客戶端存儲數據。IndexedDB允許您存儲和檢索用鍵索引的對象,以便對存儲在其中的數據進行高性能搜索。IndexedDB暴露了一個異步API,以避免阻塞DOM的加載。但一些研究表明,在某些情況下,它是阻塞的。使用IndexedDB時我推薦使用一些第三方庫,因為在JavaScript中操縱它可能非常冗長復雜。例如:localForage、idb 和 idb-keyval這些第三方模塊都是很好滴。
indexDB在瀏覽器的兼容性
Cache API:這是存儲URL地址資源的最佳選擇。和Service worker配合是非常好滴。
PouchDB:是CouchDB的開源JavaScript數據庫。它使應用程序能夠在本地存儲數據,離線,然后同步與CouchDB和兼容的服務器應用程序時重新上線,保持用戶數據同步,不管他們下一次在哪里登錄。PouchDB支持所有現代瀏覽器,使用IndexedDB引擎失敗的話就降級到WebSQL,對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, 它有簡單的 api去操作存儲鍵值對數據。
Web Storage 的瀏覽器兼容表
WebSQL:這是瀏覽器的關系型數據庫解決方案。它是已經被廢棄,因此,瀏覽器將來可能不支持它。
根據PouchDB的維護者 Nolan Lawson說,在使用數據庫時,最好問自己這些問題:
這個數據庫是在內存中還是在磁盤上?(PouchDB, IndexedDB)?
什么需要存儲在磁盤上?應用程序關閉或崩潰時應該保存哪些數據?
需要什么索引才能執行快速查詢?我可以使用內存索引而不是磁盤的嗎?
我應該怎樣構造我的內存數據相對于我的數據庫數據?我在這兩者之間的映射策略是什么?
我的應用程序的查詢需求是什么?展現視圖真的需要獲取完整的數據,還是只需要獲取它所需要的一小部分呢?我可以延遲加載任何東西嗎?
您可以查看考慮如何選擇數據庫,以便更全面地了解主題內容。
廢話少扯,讓我們實現即時加載在我們的 web app 中,我們將用localStorage,由于我在本教程前面強調的局限性,我建議你不要在生產環境中使用localStorage。我們正在構建的應用程序非常簡單,所以是使用了localStorage。
打開你的js/latest.js文件,我們更新fetchCommits方法去存儲從 Github API 拉取的數據,存儲在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); }); };
上面有這段代碼,在第一頁加載的時候,這些提交的數據就存儲到localStorage了,現在我們寫另外一個函數去渲染這些localStorage的數據。代碼如下:
// 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!" + "
"; } };
這段代碼將數據從本地存儲并將其渲染 dom 節點。
現在我們需要知道,什么條件去調用fetchCommits函數和fetchCommitsFromLocalStorage函數。
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.."); } })();
在上面的代碼片斷,我們正在檢查瀏覽器是否支持本地存儲,如果它支持,我們繼續檢查是否已經緩存了提交數據。如果沒有被緩存,我們將請求數據,顯示到頁面上并且緩存請求的數據。
現在,從新刷新一遍瀏覽器,確保你做了一個清晰的緩存,強制刷新,否則我們不會看到我們的代碼更改的結果。
現在,離線并加載最新頁面。將發生了什么事呢?
Yaaay!!! 它加載數據沒有任何問題。
查看DevTools,你間看到數據已經被緩存到localStorage
當用戶離線時,看看它加載的速度!!!
還有一件事現在,我們可以立即從本地存儲獲取數據。但是我們如何獲得最新的數據?當用戶在線時,我們需要一種仍然獲得新數據的方法。
so easy, 讓我們添加一個刷新按鈕,觸發一個請求到GitHub獲得的最新數據。
打開latest.html文件,并且添加一個刷新按鈕到
添加的按鈕后
PWA - Commits
最后,讓我們在按鈕上附加一個單擊事件并添加功能。打開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!!!"); });
清除緩存并重新加載。現在,你的latest.html頁面看起來應該像這樣:
每當用戶需要最新數據時,他們只需單擊刷新按鈕即可。
附加:
點擊查看下面鏈接
上一篇: 譯介紹一下漸進式 Web App(離線) - Part 1
原文地址
項目代碼地址
個人博客地址
如果有那個地方翻譯出錯或者失誤,請各位大神不吝賜教,小弟感激不盡
期待下一篇: 介紹一下漸進式 Web App(消息推送) - Part 3
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/112899.html
摘要:在上一篇,介紹一下漸進式離線的文章中,我們討論了典型的應該是什么樣子的并且同時也介紹了。暴露了一個異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開并且添加如下代碼清除緩存并重新加載。 在上一篇,介紹一下漸進式 Web App(離線) - Part 1的文章中,我們討論了典型的pwa應該是什么樣子的并且同時也介紹了 server worker。到目前為止,我們已經緩...
摘要:在上一篇,介紹一下漸進式離線的文章中,我們討論了典型的應該是什么樣子的并且同時也介紹了。暴露了一個異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開并且添加如下代碼清除緩存并重新加載。 在上一篇,介紹一下漸進式 Web App(離線) - Part 1的文章中,我們討論了典型的pwa應該是什么樣子的并且同時也介紹了 server worker。到目前為止,我們已經緩...
摘要:基本上是使用現代技術構建的網站但是體驗上卻像一個移動,在年,谷歌工程師和創造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗。檢查谷歌瀏覽器的和現在重載你的并且打開,到選項去查看面板,確保這個選項是勾選的。 Web開發多年來有了顯著的發展。它允許開發人員部署網站或Web應用程序并在數分鐘內為全球數百萬人服務。只需一個瀏覽器,用戶可以輸入URL就可以訪問Web應用程序了。隨著 Prog...
摘要:基本上是使用現代技術構建的網站但是體驗上卻像一個移動,在年,谷歌工程師和創造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗。檢查谷歌瀏覽器的和現在重載你的并且打開,到選項去查看面板,確保這個選項是勾選的。 Web開發多年來有了顯著的發展。它允許開發人員部署網站或Web應用程序并在數分鐘內為全球數百萬人服務。只需一個瀏覽器,用戶可以輸入URL就可以訪問Web應用程序了。隨著 Prog...
摘要:基本上是使用現代技術構建的網站但是體驗上卻像一個移動,在年,谷歌工程師和創造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗。檢查谷歌瀏覽器的和現在重載你的并且打開,到選項去查看面板,確保這個選項是勾選的。 Web開發多年來有了顯著的發展。它允許開發人員部署網站或Web應用程序并在數分鐘內為全球數百萬人服務。只需一個瀏覽器,用戶可以輸入URL就可以訪問Web應用程序了。隨著 Prog...
閱讀 1701·2021-11-18 10:02
閱讀 2218·2021-11-15 11:38
閱讀 2666·2019-08-30 15:52
閱讀 2190·2019-08-29 14:04
閱讀 3230·2019-08-29 12:29
閱讀 2086·2019-08-26 11:44
閱讀 994·2019-08-26 10:28
閱讀 830·2019-08-23 18:37