如何让你的 PWA 离线工作

已发表: 2020-01-10

目录

您可能已经知道 Progressive Web App 及其改变行业的功能已经是什么了,但是为了迭代,让我们再次重复一下可能彻底改变 Web 体验的惊人的、独特的 PWA 功能,那就是它的离线功能.

 推荐阅读:什么是 PWA?

与只能通过连接查看内容的普通 Web 不同,Progressive Web App 的不同之处在于,一旦服务工作者(一种负责 PWA 的许多渐进式功能的内置机制)加载了必要的文件,离线查看将成为可能,用户即使在离线时也可以与应用程序交互。

渐进式 Web 应用程序和离线可用性

要了解 PWA 的所有大惊小怪——尤其是它的离线功能,也许是时候亲身体验一下我们的主网站的离线查看了,这也是 PWA 的定义。

使用 PWA 离线查看内容

使用 Progressive Web Apps,整个离线体验与您的典型连接体验没有什么不同——这就是它的美妙之处。 此功能对于需要不间断浏览体验的电子商务商店特别有用,即使在没有连接的情况下也是如此。

注意:每个 PWA 站点都需要先对基本资源进行初始缓存,然后才能为用户提供离线查看功能。

如何让你的 PWA 离线工作

深入了解构建一个功能齐全、支持离线的渐进式 Web 应用程序的所有细节会很复杂,这就是为什么今天我们首先从基础开始。 我们的目标是制作一个可以离线工作的准系统 Progressive Web App

先决条件

  • 一个普通的网站/网络应用程序。 一个index.html ,一个index.js和一个style.css的任何东西都可以。

准备好所有先决条件后,就该让准系统 PWA 离线工作了!

创建一个基本的服务工作者

首先,您需要创建sw.js ,其中包含功能性服务工作者的所有必要代码。

 // sw.js
self.addEventListener("fetch", event => {
    console.log("你取到了" + event.url);
});

一旦你创建了你的 service worker,让我们检查你的浏览器是否支持它并在你的index.js中引用它:

 // index.js
if(导航器中的“serviceWorker”){
    navigator.serviceWorker
        .register("sw.js")
        .then(() => console.log("已注册服务人员!"));
}
// 页面的其余代码...

上面的代码应该足够简单。 它会检查您的浏览器是否支持服务工作者,如果支持,则返回一个“已注册的服务工作者! ”。 通过注册服务工作人员,您实际上是在告诉浏览器使用sw.js作为服务工作人员的指令,进而将新的服务工作人员与您的站点相关联。

现在,回到sw.js ,添加以下代码:

 // sw.js
self.addEventListener("fetch", event => {
    console.log("你取到了" + event.url);
});

该代码添加了一个EventListener ,这对我们的进一步操作至关重要。 事实上,包括 Chrome 在内的许多浏览器都不允许安装您的 PWA,除非注册了fetch listener。

上面代码中的addEventListener有两个参数:要监听的事件和接受事件对象的回调。 一旦此事件到位,您的服务工作者现在将开始侦听fetch事件,其中包括对您网站的 HTML、CSS、JS、音频、图像的请求以及对 API/其他网站的任何其他请求。

SimiCart 服务人员
可以使用 Chrome DevTools 检查 Service Worker

缓存你的资源

为了让您的 PWA 具备离线功能,服务人员需要为内容提供部分费用,但您还需要缓存页面的资源。

要缓存页面的资源,首先需要规划缓存存储的大小,因为它是有限制的。

缓存存储限制

每个浏览器都有不同的处理缓存存储的方式。 然而,几乎所有这些都对缓存存储的大小有限制——这个限制通常是为什么你看不到像亚马逊这样的大型肥胖网站使用服务工作者缓存他们的整个商店的原因。

现在,这个限制会有所不同,因为它取决于最终用户的设备; 但通常它应该是用户最大磁盘空间的 20% 左右。 有关更多信息,您可以参考下面的图表或 Google 的关于渐进式 Web 应用程序离线存储的官方指南。

PWA 的离线存储限制

现在我们已经解决了这个缓存存储限制,让我们继续实际缓存您的资源

要缓存页面的资源,我们需要一个包含我们要存储的所有资产的全局数组:

 /* 
  这是我们要保存在缓存中的所有内容。
  为了使应用程序可以离线工作/可安装,
  我们不仅要保存图像,还要保存我们的 HTML、JS 和 CSS
  以及 - 我们想在离线时使用的任何东西。
*/
常量资产 = [
    "https://i.imgur.com/Kbkqr2n.png",
    "https://i.imgur.com/lgLaG0x.png",
    "https://i.imgur.com/0iL8mxP.png",
    "https://i.imgur.com/KDsdYeS.png",
    "https://i.imgur.com/mK50fqL.png",
    "https://i.imgur.com/KYGH2Qa.png",
    "/style.css",
    "/index.html",
    "/offline.html",
    “/”
];

这是存储您要离线使用的所有内容的地方。 在上面的示例中,前几张图像是 Imgur 的路径,其中存储了各种 SimiCart 的徽标。

通过这一步,我们离线使用的必要资源列表现已准备就绪。 让我们使用服务工作者缓存它们。

在 sw.js 的顶部添加这个顶部:

 // sw.js

让 cache_name = "SimiCart"; // 用于标识我们的缓存的字符串

self.addEventListener("安装", 事件 => {
    console.log("正在安装...");
    事件.waitUntil(
        缓存
            .open(缓存名称)
            .then(缓存 => {
                返回 cache.addAll(assets);
            })
            .catch(err => console.log(err))
    );
});

本质上,此代码指示浏览器等待(使用waitUntil()调用)我们的缓存。

通过使用缓存 API,特别是addAll() ,我们的资产数组可以毫不费力地添加到缓存中,准备好由服务人员提供服务。 好吧,再想一想,它还没有准备好。 我们仍然需要稍微修改我们的fetch事件处理程序。

这就是它现在的样子:

 self.addEventListener("fetch", event => {
    if (event.request.url === "https://www.simicart.com/") {
        // 或者你的应用的 URL 是什么
        event.respondWith(
            fetch(event.request).catch(err =>
                self.cache.open(cache_name).then(cache => cache.match("/offline.html"))
            )
        );
    } 别的 {
        event.respondWith(
            fetch(event.request).catch(err =>
                caches.match(event.request).then(response => response)
            )
        );
    }
});

现在在上面的代码中应该很清楚,即使应用程序处于离线状态,我们也会尝试缓存资源。 逻辑如下:

  • 首先,如果获取失败(使用respondWith() ),应用程序会尝试在线获取资源并使用缓存的资源进行响应。
  • respondWith()中,我们调用fetch(event.request)来尝试从网络中获取资源,并且由于 fetch 是基于Promise的,如果无法连接到网络, Promise将拒绝,进而触发catch()声明。
  • catch()语句中是您想要调用缓存资源的地方。

就是这样。 您的 PWA 现在应该可以离线工作了! 很容易,不是吗?

结论

在技​​术世界中,事情发展得非常快,您等待转换为 PWA 或将重要功能(例如离线功能)集成到您的 PWA 中的时间越长,您和您的业务的机会成本就越高。

尽管如此,仍然有现成的解决方案提供商,例如 SimiCart,可以满足您的所有需求。 如果您碰巧是一名在线商家并正在寻找全方位完美的Magento PWA解决方案,那么您来对地方了。 我们是 Magento 电子商务网站的知名解决方案提供商,在 PWA 和原生应用方面拥有超过 5 年的专业知识。

使用 SimiCart自定义您的 PWA