摘要:在上一篇,介绍一下渐进式离线的文章中,我们讨论了典型的应该是什么样子的并且同时也介绍了。暴露了一个异步,以避免阻塞的加载。但一些研究表明,在某些情况下,它是阻塞的。打开并且添加如下代码清除缓存并重新加载。
在上一篇,介绍一下渐进式 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
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92153.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...
阅读 1132·2023-04-25 17:28
阅读 3422·2021-10-14 09:43
阅读 3913·2021-10-09 10:02
阅读 1923·2019-08-30 14:04
阅读 3105·2019-08-30 13:09
阅读 3249·2019-08-30 12:53
阅读 2868·2019-08-29 17:11
阅读 1800·2019-08-29 16:58