首页 > 解决方案 > 将 TransferState 与 PWA 一起使用是否合理?

问题描述

当我在 Angular 5 中使用 Universal 创建我的应用程序以实现服务器端渲染时,我使用 TransferState 来不将我的请求复制到 API 端点。

我已将我的应用程序升级为 Progressive Web APP,但现在浏览器请求所有资源。据我了解,node.js 服务器发送的 index.html 无法发送带有状态数据的 html。

那么当应用程序作为 PWA 工作时使用 TransferState 是否合理?

标签: angularprogressive-web-appsangular-universalserver-side-rendering

解决方案


是的,在 Angular 中使用 Transferstate 和 PWA 是合理的,但有一点需要注意。

Transferstate 将在您第一次访问 webapp 时生效。Angular Universal 将完全呈现与您的 URL 匹配的视图的 html,并按照您的预期发送通过 Transferstate 检索到的任何数据,以防止在客户端应用程序加载并再次进行所有相同的 API 调用时发生“flash” .

在后台,ServiceWorker 将缓存或主动下载应用程序的额外 PWA 元素,例如index.html文件。之后,对 webapp 的后续访问将完全由现在缓存在浏览器中的 PWA 处理,从浏览器启动任何 API 调用,完全绕过服务器端渲染和传输状态的需要。即使您碰巧在您从未访问过的路线上跳入 web 应用程序,也会发生这种情况。

在这种情况下,transferstate 的目的是防止在支持 PWA 的浏览器上首次访问 webapp 时发生“flash”,以及对于不支持 PWA 的浏览器的后续访问 webapp,因为这些请求将始终转到Angular 通用服务器。

这里需要注意的是,传输状态不应被视为唯一可能的数据来源。如果您要查找的数据不在传输状态中,则应该始终有一些 API 可供回退。

我个人经验的一个例子:我正在使用 transferstate 将从服务器的环境变量读取的配置值发送到浏览器。当 PWA 接管时,由于 PWA 的 index.html 中没有传输状态,因此找不到配置。解决方案是设置一个 API 端点来提供配置,而不是依赖于传输状态。

上一个答案(忽略此处的建议):

将 Transferstate 与 PWA 一起使用时似乎存在限制。我发现在“DOMContentloaded”触发器触发时,存储 Transferstate json 的脚本标签不在 DOM 中。

使用 Chrome Devtools 打开应用程序选项卡,在“服务工作者”下取消选中“重新加载时更新”和“绕过网络”框。然后重新加载您的应用程序并观察您可能缓存在 Transferstate 中的任何 XHR 请求实际上是在浏览器中发出的,尽管它们应该已经在服务器端渲染期间发出。

这并不完美,但一种选择是从 ngsw-config.json 文件中的任何assetGroups.resources.files 数组中删除 /index.html 条目。这可以防止您的应用程序成为具有离线功能的完整 PWA,但它仍然具有从服务工作者加载其他资源的好处。


推荐阅读