借助PRPL加快Web应用交付速度

2020-10-19 07:53:22

PRPL是一种构建和服务Web应用程序和渐进式Web应用程序(PWA)的模式,强调改进应用程序交付和启动性能。这些信件描述了一套有序的步骤,以实现快速、可靠、高效的装载:

推送初始路径所需的所有资源(包括并且仅推送这些资源),以确保它们尽早可用。

为用户可能访问的其他路由预缓存资源,最大限度地提高对后续请求的响应能力和在网络条件较差时的恢复能力。

根据用户请求按需延迟加载路由;关键路由的资源应立即从缓存加载,而不常用的资源可根据请求从网络获取。

注意:PRPL模式是由聚合物团队在2016年首次引入的,但已经证明自己适用于许多其他堆栈。

服务器和服务工作者共同为非活动路由预缓存资源。当用户切换路线时,应用程序会延迟加载任何尚未缓存的所需资源,并创建所需的视图。

Twitter.com自2017年以来一直在生产中使用PRPL模式。下面,我们可以看到他们对关键脚本使用粒度代码拆分,并使用<;link rel=preload>;来推送它们,以便它们尽早可用:

额外的航线是按需懒惰加载的,Twitter在整个用户体验中按需提供40多个区块。Twitter还(离线)使用服务工作者(Service Worker)为资产预留额外的路线,以提高对后续导航的响应能力:

他们的应用程序外壳(骨架UI)也是离线缓存的,即使用户在缓慢或参差不齐的网络连接上加载站点,也会立即加载:

使用PRPL构建的应用程序力求可靠、快速和引人入胜。除了这些基本目标之外,PRPL的目标是:

提高应用程序的交互就绪性。它通过确保在第一个视图呈现和交互之前不会将无关资源发送到浏览器来实现这一点。

提高应用程序的缓存效率,特别是随着时间的推移。它通过以高粒度将资源发送到浏览器来实现这一点。当资源拆分或绑定不那么积极时,对代码的每一次更改都会减少缓存的无效部分。

降低开发和部署的复杂性。它依靠应用程序的隐式依赖图将每个入口点映射到所需的精确资源集,从而减少或消除了手动管理捆绑和交付的需要。

这是一种有用的心态,因为今天的典型应用程序比它需要的要重得多。为了帮助在移动网络上提供更好的体验,我们需要从整体上让应用程序变得更轻。这意味着理解并仔细考虑我们包含的所有内容的权重-包括我们自己的代码和我们的依赖项。

但这还不够。我们也在以一种低效的方式交付我们的应用程序,通常是提供包含应用程序全套资源的一体化捆绑包。在用户可以执行任何操作之前,必须在客户机上完整地接收和处理此捆绑包。展望未来,我们需要构建和服务我们的应用程序,以便:

根据用户的初始请求,我们只交付和处理支持所请求路径所需的资源,以确保我们的应用程序能够以最快的速度进行交互

一旦互动,我们就开始机会主义地交付所需的额外资源,以确保我们的应用程序能够立即响应后续用户请求。

我们应用程序的未来更新效率最高,消耗的带宽和时间尽可能少。

PRPL是一个概念性模式,可以通过各种方式实现,但通过利用以下现代Web功能的某种组合可以最容易、最有效地实现它:

像JavaScript Modules这样的现代模块系统,这样工具就可以很容易地构建完整的依赖图。

预加载,以便尽快交付所需的资源。您还可以利用预加载链接标头,这些标头可以被协作的服务器截获并升级为HTTP/2服务器推送响应。重要的是要记住,虽然功能强大,推送有已知的挑战,但是PRPL##39;使用服务工作者可以避开过度推送的问题(只推送初始加载)。

PRPL的很大一部分是颠覆JS捆绑的思维模式,交付尽可能接近创作粒度的资源(至少在功能独立的模块方面)。您如何实现粒度?

你已经在把东西写成组件了。也许您正在使用ES模块。对于webpack,我们使用动态导入和代码拆分将您的代码库拆分成按需加载的块。

Next.js和Nuxt.js等元框架默认实现基于路由的代码拆分。如果您使用的是诸如create-action-app之类的工具样板,那么您将依赖于使用诸如Reaction Router之类的路由器的动态导入来向您的应用程序添加基于路由或基于组件的代码拆分。

对于PRPL的Push/Preload部分,webpack还支持将Preload作为预加载关键脚本的神奇注释。

预缓存剩余的路由可以使用服务人员来实现。利用诸如WORKBOX之类的服务工作者库来简化为应用程序预缓存路由和块的过程并不少见。

应用程序的主要入口点,从每条有效路由提供服务。此文件应该非常小,因为它将从不同的URL提供服务,因此会被多次缓存。入口点中的所有资源URL都需要是绝对的,因为它可能来自非顶级URL。

应用程序的延迟加载片段。片段可以表示特定视图的代码,也可以表示可以延迟加载的其他代码(例如,第一次绘制时不需要的主应用程序部分,比如直到用户与应用程序交互后才会显示的菜单)。外壳负责根据需要动态导入片段。

应用程序应该调用动态导入来延迟加载片段,因为它们是需要的。例如,当用户更改到新路由时,它会导入与该路由相关联的片段。这可以向服务器发起新的请求,或者简单地从高速缓存加载资源。

PRPL是一种自2016年引入以来一直在大规模使用的模式,并且仍然是一种值得考虑为您的应用程序加载的值得考虑的方法。

归功于格雷·诺顿、凯文·沙夫、亚历克斯·罗素和其他许多人,他们多年来对PRPL和PRPL指导做出了贡献。特别感谢Twitter.com批准在这篇文章中使用截图。