架构

要充分利用使 PWA 可靠、可安装和功能强大的技术来设计您的应用程序,首先要了解您的应用程序及其约束,并为两者选择合适的架构。

SPA 与 MPA

如今,Web 开发中有两种主要的架构模式:单页应用 (SPA) 和多页应用 (MPA)。

单页应用的定义是:客户端 JavaScript 控制页面的大部分或全部 HTML 呈现,而 HTML 呈现基于应用检索或提供给应用的数据。应用会替换浏览器的内置导航,并将其替换为自身的路由和视图处理功能。

多页应用通常将预呈现的 HTML 直接发送到浏览器,通常在浏览器完成 HTML 加载后通过客户端 JavaScript 进行增强,并依靠浏览器的内置导航机制来显示后续视图。

这两种架构都可用于创建 PWA。

每种架构都有优点和缺点,为您的用例和环境选择合适的架构是为您的用户提供快速可靠体验的关键。

单页应用

优点
  • 主要是原子性的页面内更新。
  • 客户端依赖项在启动时加载。
  • 后续加载速度很快,因为使用了缓存。
缺点
  • 初始加载成本高。
  • 性能取决于设备硬件和网络连接。
  • 需要额外的应用复杂性。

如果出现以下情况,单页应用是一个不错的架构选择

  • 用户交互主要围绕同一页面上显示的互连数据的原子性更新,例如,实时数据信息中心或视频编辑应用。
  • 您的应用程序具有仅限客户端的初始化依赖项,例如,启动成本过高的第三方身份验证提供程序。
  • 视图加载所需的数据依赖于特定的仅限客户端的环境,例如,显示连接硬件的控件。
  • 应用足够小且足够简单,以至于其大小和复杂性不会对上面列出的缺点产生影响。

如果出现以下情况,SPA 可能不是一个好的架构选择

  • 初始加载性能至关重要。SPA 通常需要加载更多 JavaScript 来确定要加载的内容以及如何显示它。此 JavaScript 的解析和执行时间,加上检索内容的时间,比发送呈现的 HTML 慢。
  • 您的应用主要在低功耗到中等功耗设备上运行。由于 SPA 依赖 JavaScript 进行呈现,因此用户体验对特定设备的性能的依赖程度远高于 MPA。

由于 SPA 需要用自身的路由替换浏览器的内置导航,因此 SPA 需要围绕有效更新当前视图、管理导航更改以及清理以前的视图(否则这些视图将由浏览器处理)的最低复杂性,这使得它们总体上更难维护,并且对用户设备的要求更高。

多页应用

优点
  • 主要是整页更新。
  • 初始渲染速度至关重要。
  • 客户端脚本可以是增强功能。
缺点
  • 辅助视图需要另一次服务器调用。
  • 上下文在视图之间不传递。
  • 需要服务器或预呈现。

如果出现以下情况,多页应用是一个不错的架构选择

  • 用户交互主要围绕单个数据片段的视图(带有可选的基于上下文的数据),例如,新闻或电子商务应用。
  • 初始渲染速度至关重要,因为将已渲染的 HTML 发送到浏览器比在加载、解析和执行基于 JavaScript 的替代方案后从数据请求中组装 HTML 要快。
  • 客户端交互性或上下文可以作为初始加载后的增强功能包含在内,例如,将个人资料分层到呈现的页面上或添加辅助客户端上下文相关的组件。

如果出现以下情况,MPA 可能不是一个好的架构选择

  • 重新下载、重新解析和重新执行您的 JavaScript 或 CSS 的成本过高。此缺点可以通过 PWA 和 Service Worker 来缓解。
  • 客户端上下文(例如用户位置)在视图之间不会无缝传递,并且重新获取该上下文的成本可能很高。它要么需要捕获和检索,要么需要在视图之间重新请求。

由于各个视图需要由服务器动态呈现或在访问之前预呈现,因此可能会限制托管或增加数据复杂性。

选择哪一个?

即使存在这些优点和缺点,这两种架构对于创建您的 PWA 都是有效的。您甚至可以根据应用程序的需求将它们混合用于应用程序的不同部分,例如,让商店列表遵循 MPA 架构,而结账流程遵循 SPA 架构。

无论选择哪种架构,下一步都是了解如何最好地使用 Service Worker 来提供最佳体验。

Service Worker 的强大功能

除了基本路由和缓存及网络响应的交付之外,Service Worker 还具有许多强大的功能。我们可以创建复杂的算法来改善用户体验和性能。

Service Worker Includes (SWI)

将 Service Worker 用作网站架构不可或缺一部分的一种新兴模式是 Service Worker Includes (SWI)。SWI 根据各个资源(通常是 HTML 页面)的缓存需求将其划分为多个部分,然后在 Service Worker 中将它们缝合在一起,以提高一致性、性能和可靠性,同时减小缓存大小。 一个带有全局标头、内容区域、侧边栏和页脚的网站。

此图片是一个示例网页。它有五个不同的部分,将页面分解为

  • 整体布局。
  • 全局标头(顶部深色栏)。
  • 内容区域(中间左侧线条和图片)。
  • 侧边栏(中间右侧高高的中深色栏)。
  • 页脚(底部深色栏)。

整体布局

整体布局不太可能经常更改,并且没有依赖项。它是预缓存的理想选择。

全局标头和页脚包含顶部菜单和网站页脚等内容,并且提出了一个特殊的挑战:如果将页面作为一个整体进行缓存,则这些内容可能会在页面加载之间发生更改,具体取决于给定页面的缓存时间。

通过将它们分离并独立于内容进行缓存,您可以确保用户始终获得相同的版本,而不管它们的缓存时间如何。由于它们不经常更新,因此它们也是预缓存的理想选择。但是,它们有一个依赖项:网站的 CSS 和 JavaScript。

CSS 和 JavaScript

理想情况下,网站的 CSS 和 JavaScript 应该使用过时但再验证策略进行缓存,以允许增量更新,而无需像预缓存资源那样更新 Service Worker。不过,每当 Service Worker 使用新的全局标头或页脚进行更新时,也需要将它们保持在最低版本。因此,当 Service Worker 安装时,它们的缓存也应该使用最新版本的资源进行更新。

内容区域

接下来是内容区域。根据更新频率,网络优先或过时但再验证是此处的理想策略。图片应该使用缓存优先策略进行缓存,如先前讨论的那样。

最后,假设侧边栏内容包含辅助内容,例如标签和相关项目,则它不是重要到需要从网络拉取的内容。过时但再验证策略适用于此。

现在,在经历了这一切之后,您可能会认为您只能对单页应用执行这种按部分缓存。但是,通过在您的 Service Worker 中采用受边缘端包含服务器端包含启发的模式,以及一些高级 Service Worker 功能,您可以对任何一种架构执行此操作。

亲自试用

您可以尝试使用下一个 Codelab 中的 Service Worker Includes

流式响应

可以使用 SPA 世界中的应用 Shell 模型创建上一页,其中应用 Shell 被缓存,然后提供服务,并且内容在客户端加载。随着 Streams API 的引入和广泛可用性,应用 Shell 和内容都可以在 Service Worker 中组合并流式传输到浏览器,从而为您提供应用 Shell 的缓存灵活性和 MPA 的速度。

之所以如此,是因为

  • 流可以异步构建,允许流的不同部分来自其他来源。
  • 流的请求者可以在第一个数据块可用后立即开始处理响应,而不是等待整个项目完成。
  • 针对流式传输优化的解析器(包括浏览器)可以在流完成之前逐步显示流的内容,从而加快响应的感知性能。

由于流的这三个属性,围绕流式传输构建的架构通常比不围绕流式传输构建的架构具有更快的感知性能。

使用 Streams API 可能具有挑战性,因为它既复杂又底层。幸运的是,有一个 Workbox 模块可以帮助您为 Service Worker 设置流式响应。

域、来源和 PWA 作用域

Web Worker(包括 Service Worker)、存储,甚至已安装 PWA 的窗口,都受 Web 上最关键的安全机制之一的约束:同源策略。在同一来源内,会授予权限,可以共享数据,并且 Service Worker 可以与不同的客户端通信。在同一来源之外,不会自动授予权限,并且数据是隔离的,并且在不同来源之间不可访问。

同源策略

如果协议、端口和主机相同,则两个网址被定义为具有完全相同的来源。

例如:https://squoosh.apphttps://squoosh.app/v2 具有相同的来源,但 http://squoosh.apphttps://squoosh.comhttps://app.squoosh.apphttps://squoosh.app:8080 位于不同的来源。有关更多信息和示例,请查看同源策略 MDN 参考

更改子域不是主机可以更改的唯一方式。每个主机都由顶级域名 (TLD)、二级域名 (SLD) 和零个或多个标签(有时称为子域)组成,它们之间用点分隔,并在网址中从右向左读取。任何一项的更改都会导致不同的主机。

窗口管理模块中,我们已经了解了当用户从已安装的 PWA 导航到不同的来源时,应用内浏览器的外观。

即使网站具有相同的 TLD 和 SLD,但标签不同,该应用内浏览器也会出现,因为它们被视为不同的来源。

Web 浏览环境中来源的关键方面之一是存储和权限的工作方式。一个来源在其中的所有内容和 PWA 之间共享许多功能,包括

  • 存储配额和数据(IndexedDB、Cookie、Web Storage、Cache Storage)。
  • Service Worker 注册。
  • 已授予或拒绝的权限(例如 Web 推送、地理位置、传感器)。
  • Web 推送注册。

当您从一个来源移动到另一个来源时,以前的所有访问权限都将被撤销,因此必须再次授予权限,并且您的 PWA 无法访问存储中保存的所有数据。

资源