您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 2浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

开发人员需要了解的渐进式Web应用程序

寒冰屋 发布时间:2021-11-03 22:18:11 ,浏览量:2

目录

介绍

无论如何,什么是PWA?

如何构建PWA

您可能(不)期待的挑战

缓存失效

缺乏API

可发现性

平台原生UI

同步

PWA在行动

介绍

2011年,我们生活的方方面面似乎都在转向网络。智能手机和平板电脑的使用量正在上升,最近完成的HTML5规范,以及诸如Web清单等不错的补充,似乎为光明的未来铺平了道路。由于时尚社交网络Facebook在其移动应用程序中大力押注HTML5,因此一切都已成形。

然后有一些不幸的挫折。首先,崭露头角的原生应用框架PhoneGap没有任何发展。Facebook然后宣布他们正在重写他们的移动应用程序。他们说HTML5还没有准备好。

最后,当Google宣布AMP(带有一些自定义元素的HTML5子集)时,没有人愿意押注HTML作为应用程序平台。诸如webOS和Mozilla的Firefox OS等失败的实验使过渡更进一步。

尽管如此,十年后,我们可以再次尝试这种转变。这一次,谷歌站在我们这边。随着过去十年中添加的浏览器API以及Chrome现在成为Android上的默认浏览器,开发人员在“渐进式Web应用程序”(PWA)这一术语下汇集了一组Web技术。PWA可以被视为真正的Web应用程序。

今天,大多数浏览器都支持PWA,但基于Chromium的浏览器肯定是最好的,例如Microsoft Edge、Brave、Opera和Google Chrome。不幸的是,Apple的Safari是支持较差的浏览器之一。尽管如此,大多数功能都适用于Safari。最大的痛点是PWA安装和推送通知。

让我们探索什么是PWA、如何构建PWA以及您可能面临的一些挑战。然后,我们将看看一些正在运行的PWA。

无论如何,什么是PWA?

根据维基百科,PWA具有以下特点:

  • 渐进式:无论选择何种浏览器,它们都适用于每个用户,因为它们以渐进式增强为核心原则构建。
  • 响应式:它们适合任何形式因素:台式机、移动设备、平板电脑和尚未出现的形式。
  • 连接独立:服务工作者支持离线工作,或在低质量的网络上工作。
  • App-like:对于用户来说,它们就像一个应用程序,具有应用程序风格的交互和导航。
  • 新鲜:由于Service Worker更新过程,它们始终是最新的。
  • 安全:它们通过HTTPS提供服务,以防止窥探并确保内容未被篡改。
  • 可发现:由于W3C清单和Service Worker注册范围,它们可以被识别为“应用程序”,使搜索引擎能够找到它们。
  • 可重新参与:它们通过推送通知等功能使重新参与变得容易。
  • 可安装:它们允许用户在主屏幕上“保留”他们认为最有用的应用程序,而无需进入应用程序商店。
  • 可链接:它们可以通过URL轻松共享,不需要复杂的安装。

这里有几个要点。关于PWA是什么或需要什么,没有规范或官方指南。提到的特征最终都是PWA的一部分。但是,开发人员可能会根据情况忽略或以不同的方式实现它们。

PWA最重要的方面是它是可安装的。这使得PWA真正成为一个Web应用程序,即手机上的应用程序。理想情况下,这也意味着应用程序可以离线工作——至少在某种程度上是这样。离线模式是一个好的PWA的核心属性。

离线模式最具挑战性的方面之一是适当的缓存失效。由于资源和HTTP请求现在缓存在客户端,您需要定义适当的策略,例如网络优先策略。理想情况下,该策略取决于资源的种类。例如,应用程序可以通过网络优先加载策略检索主页,但其所有相关资源都有一个经过哈希处理的文件名。这使得所有其他资源都适合缓存优先加载策略。

最后,认真对待进步点。我们仍然应该尊重我们在引入HTML5时学到的一切,例如使用不显眼的JavaScript,使用媒体查询进行响应式设计,以及通过回退元素和可访问的富互联网应用程序(ARIA)属性提供可访问性。

现在让我们将这些知识付诸实践。

如何构建PWA

虽然一个不引人注目且响应迅速的网站代表了一个很好的基础,但它——至少根据上一节的定义——不是PWA。相反,主要目标是控制资源和请求的执行方式,但这是如何实现的?虽然标准XMLHttpRequest或fetch API可能被抽象掉,但没有直接的方法来覆盖如何解决一般资源获取,例如脚本源或样式表链接。

这个谜语的答案是服务工作者。通过调用navigator接口的serviceWorker API上的register方法,您可以引入另一个脚本,该脚本在网站的普通浏览上下文之外运行。然后浏览器使用这个脚本来确定各个方面——最重要的是拦截HTTP调用。

// check for support
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('my-service-worker.js');
}

为了注册工作:

  • 必须通过HTTPS为工作人员提供服务。
  • 路径一定是对的。
  • 来源必须与应用程序来自同一来源。

service worker不处理所有请求,只处理与worker范围匹配的请求。范围主要由Service Worker的位置决定,尽管它可能会通过某些注册选项进一步受到限制。

在进入Service Worker之前,有必要先了解一下在创建PWA时通常应该涵盖的另一个方面:Web清单。

有了HTML5,缓存清单就诞生了。这个文件——从文档的根元素(即html标签)链接——有一个自定义语法来定义要缓存的内容和替换的内容,以及离线时的内容。虽然Service Workers主要履行这个角色,但描述性元文件的概念仍然很有吸引力。PWA使用Web清单来实现这一点。

应用程序通过link标签链接到Web清单,就像样式表一样:

要有效,文件本身必须设置四个值:

  • 较长的完整应用程序名称( name)
  • 应用程序名称的缩写(short_name)
  • 实际根或起始页,以防清单被重用或在单页应用程序(SPA)中使用(start_url)
  • 安装后应用程序的显示方式(display)

显示的允许值为standalone或fullscreen。该值的解释完全留给浏览器。其他属性,例如theme_color或background_color,也取决于浏览器或操作系统(OS)端的实现。大多数情况下,它们有助于更恰当地显示仪表板图标和应用程序打开时的启动画面。

大多数实现要求清单定义一个144x144像素的图标——否则,清单仍被视为有效,但不足以使Web应用程序可安装。

完整的清单可能如下所示:

{
  "name": "Example App",
  "short_name": "ExApp",
  "display": "standalone",
  "start_url": "/",
  "icons": [
   {
     "src": "/images/icon-144.png",
      "sizes": "144x144",
     "type": "image/png"
   }
  ]}

大量工具和资源有助于生成有效且有用的清单文件,例如Web App Manifest Generator。

对于Service Worker,有两种选择:

  • 使用现有的库或框架为我们提供Service Worker所需的一切。
  • 自己实现适当的缓存和回退命令。

第二种选择起初似乎可行。毕竟,在Service Worker中处理HTTP请求就像编写代码一样简单:

self.addEventListener('fetch', e => {
  // Empty for now
});

通常,这些事件很重要。例如,如果您想在PWA安装时缓存其他文件,您可以使用该install事件。在代码中:

self.addEventListener('install', async e => {
  const cache = await caches.open('files');
  cache.addAll([
    './script.js',
    './style.css',
    './assets/image.png',
  ]);
});

缓存API的美妙之处在于您只需要提供这些相对路径,其余的由浏览器完成。浏览器按照您的预期获取URL并将它们放入缓存中。

处理fetch事件很快就会变得乏味。起初,这可能看起来不太糟糕,但可靠地处理网络(并使用正确的缓存策略)具有挑战性。

网络优先策略通常是一个很好的起点。不是使用缓存来增强性能,而是仅将缓存用作后备,即在离线时使用。快速实现可能是:

self.addEventListener('fetch', async e => {
  const req = e.request;
  const cache = await caches.open('data');

  try {
    const res = await fetch(req);
    cache.put(req, res.clone());
    await e.respondWith(res);
  } catch {
    const res = await cache.match(req);

    if (res) {
      await e.respondWith(res);
    } else {
      e.respondWith(getFallback(req));
    }
  }
});

在此代码示例中,该getFallback函数为一些最初定义的回退数据实现了缓存查找。否则,只返回“未定义”。

这个简单的例子表明一个实现可能会很快失控。更好的选择是使用现有的工具和库,例如Workbox。例如,通过与webpack bundler的集成,它可以方便地生成一个自我更新的service worker,具有适当的缓存失效规则,并且可以使用预先选择的缓存策略进行配置。

让我们看看您可能面临哪些其他挑战,即使您使用专门的工具来创建PWA。

您可能(不)期待的挑战

PWA有一些我们需要解决的挑战,最突出的是:

  • 缓存失效
  • 缺乏API
  • 可发现性
  • 平台原生用户界面(UI)
  • 同步

让我们一一看看这些挑战。

缓存失效

IT中存在三个主要问题:缓存失效、命名和一对一错误。缓存失效问题最初对Service Worker来说似乎有些微不足道,但当空间有限时,它可能很快就会成为一个真正的问题。因此,您不能只缓存每个请求。如果这样做,您可以缓存根据定义仅给出初步和临时结果的请求。

缓存过多请求的结果之一可能是“超出配额”错误形式的异常。这些错误非常令人讨厌。它们甚至可能不是来自同一个应用程序,因为不同的配额可能会遇到以下错误:

  • 相应的请求、数据或缓存
  • 应用程序
  • 用户的个人资料
  • 浏览器整体
  • 整机

例如,对于在隐身模式下运行的应用程序,谷歌浏览器最多可允许100MB。在任何情况下,具体限制和行为取决于服务浏览器。这里比较保守是有道理的。

缺乏API

原生移动开发的一大优点是所有必要的API都已经可用。想要在后台进行地理围栏?是有的。想使用指纹传感器?是有的。想要保护特殊保管库中的私人数据?是有的。尽管Web现在拥有大量改进的API,包括支付API、蓝牙API等,但这些可能不足以满足您的用例。

此外,尽管存在API,但它可能尚未在目标平台上可用。以支付API为例。在移动平台上,支持率看起来不错,超过90%(见下图)。但是,由于支付API被拆分为多个区域,因此某些部分的支持可能较少。在投入生产之前进行检查和测试是有意义的。

当然,始终可以选择将PWA打包到本机应用程序包中。这样,本机API可能可用,本机应用程序分发可以限制目标平台。

可发现性

如果我们将PWA视为原生应用的网络原生替代品,那么我们就会错过一个中央应用商店。当然,这也是PWA的优势之一。没有中央看门人意味着更大的灵活性,但这也意味着用户很难找到您的PWA。

幸运的是,有多种方法可以解决这个问题。一方面,您可以将PWA提交到现有的PWA目录。另一种方法是将PWA打包在本机应用程序中——和以前一样——并且仍然通过各自的中央应用程序商店。最后,由于PWA仍然只是一个网站,您可以使用您的网站来正确地宣传它。可发现性可能不是很好,但它肯定不比标准网站差。

平台原生UI

将PWA视为原生应用程序的替代品也会影响整体UI和用户体验(UX)设计。应用程序应该尽可能尊重底层平台的本机外观和行为,但这应该如何工作?毕竟,有多个平台,大概您甚至不是在应用程序模式下运行,而是在标准浏览器shell中运行。

至少存在一个CSS媒体查询,用于找出应用程序正在运行的模式:

@media all and (display-mode: standalone) {
  body {
    /* … */
  }
}

对于底层平台,navigator.platform可能有用。尽管如此,您必须实现大量函数来尽可能地模仿平台行为。即便如此,用户也可以识别出该应用程序不是原生的。

同步

回到缓存失效,问一个问题是有道理的:应用程序在重新上线时应该如何同步数据?

假设用户离线并提交了一个表单。您的逻辑可以将该提交放入队列中,并在用户重新在线时将其推送到服务器。虽然这可以使用在线/离线浏览器事件与navigator.onLine相结合,但困难可能在于细节。常见的挑战包括对其他请求的依赖、处理提交失败和减轻重放问题。

PWA在行动

PWA对开发人员和公司有吸引力的原因有很多。一个绝对是绕过苹果和谷歌等应用商店供应商围墙花园的能力。

目前,网上有一些非常出色的PWA“商店”。与经典应用商店相比,这些是目录而不是系统商店。该类别中的一个示例是Appscope。它的简约和直截了当的设计强调了大多数PWA试图实现的目标。

该网站重点介绍了许多出色的PWA,不仅来自一些大型科技公司,还来自独立开发人员和业余爱好者。任何人都可以提交条目,版主会在每个条目上线之前对其进行审核。

尽管有许多令人印象深刻的PWA示例,但最好的PWA并不总是显而易见的。以Word和Excel等Microsoft Office 365 Web应用程序为例。它们可以在所有维度和跨多个设备上工作——尽管有时仅以简化模式(例如只读)工作。即使关闭,它们也会通知您更新,并且始终使用最新资产进行更新。

许多流行的应用程序现在也通过PWA出现在网络上,例如成功的初创公司Tinder、Uber和Pinterest。另一个PWA示例是开源电子病历记录系统OpenMRS的下一个版本。虽然以前的版本使用服务器端呈现的UI,但他们的下一个版本将附带一个打包为PWA的新单页应用程序。通过这种方式,以前不可能进行的活动,例如在记录患者观察或做笔记时离线,现在变得可行。

总体而言,向PWA的过渡非常简单,特别是对于类似工具的Web应用程序来说是有意义的。

What Developers Need to Know About Progressive Web Apps - CodeProject

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.1515s