QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

PRPL 模式加快 Web 应用加载

  • 2020-12-04
  • 本文字数:2296 字

    阅读完需:约 8 分钟

PRPL模式加快Web应用加载

PRPL 是一种用于结构化和交付 Web 应用程序和渐进式 Web 应用(PWA)的模式,重点在于改进应用的交付和启动性能。这个模式包含一组步骤,以实现快速、可靠、高效的加载:


  • Push,推送初始路由所需的所有资源,并且只推送这些资源,以确保它们尽早可用。

  • Render,在加载其他资源之前,渲染初始路由并使其具备交互能力。

  • Pre-cache,预缓存用户可能访问的其他路由的资源,从而在恶劣的网络条件下尽可能提高对后续请求的响应能力和弹性。

  • Lazy-load,当用户请求时,按需延迟加载路由;关键路由的资源应立即从缓存中加载,而相对不常用的资源可以根据请求从网络获取。


注意:PRPL 模式是由 Polymer 团队于 2016 年首次引入的,但已被证明适用于其他许多技术栈。


PRPL 模式加载顺序


服务器和服务 Worker 一起为非活动路由预缓存资源。当用户切换路由时,应用会延迟加载尚未缓存的所有必需资源,并创建所需的视图。


Twitter.com 自 2017 年以来就在生产中使用 PRPL 模式了。下面我们可以看到,他们对关键脚本使用了粒度代码拆分,并使用<linkrel=preload>推送脚本以尽快让脚本可用:


PRPL 模式:预加载关键脚本


其他路由会按需延迟加载。Twitter 在整个用户体验部分中会按需提供 40 多个块。Twitter 还使用服务 Workers 对其他路由进行(离线)资产预缓存,以提高对后续导航操作的响应能力:


PRPL 模式:离线缓存资源


他们的应用程序外壳程序(骨架 UI)也是离线缓存的,就算用户通过缓慢或不稳定的网络连接加载站点,也会立即加载它们:


PRPL 模式:应用程序外壳


为什么选择 PRPL?


应用使用 PRPL 构建是为了达到可靠、快速和引人入胜的目的。除了这些基本目标,PRPL 还旨在:


  • 改善应用的交互就绪水平。为了做到这一点,在第一个视图渲染并具备交互能力之前,不会向浏览器发送多余的资源。

  • 提高应用的缓存效率,尤其是长期缓存效率。为了做到这一点,资源会以很细的粒度向浏览器发送。当资源被解绑或松散地打包时,对代码的每次更改给缓存的负面影响也会减少。

  • 降低开发和部署的复杂性。为了做到这一点,这种模式使用应用的隐式依赖图将每个入口点精确映射到所需的资源集,从而减少或消除了手动管理打包和交付的需求。


这是一种很有意义的理念,因为今天典型的应用太过臃肿了。为了帮助开发人员在移动 Web 端提供更好的体验,我们首先要做的是让应用变轻变小。这意味着我们要理解并仔细考虑包含在应用中所有内容的权重——包括我们自己的代码及其依赖项。


但这还不够。我们还在以低效的方式交付应用,通常会把应用的全部资源打进一个包里。用户必须在客户端上完整地接收并处理这个包后,才能开始操作。展望未来,我们在构建和提供应用时需要做到:


  • 根据用户的初始请求,我们只交付和处理支持所请求路由的那些资源,以让应用尽早准备好交互;

  • 交互就绪后,我们将开始提供其他必要的资源,以确保应用能够立即响应用户的后续请求;

  • 应用的未来更新应最大限度地提高效率,并消耗尽可能少的带宽和时间。


PRPL 应包含哪些技术?


PRPL 是一种能以各种方式实现的概念模式,但是通过以下现代 Web 特性的某种组合,可以最轻松有效地实现 PRPL:


  • 像 JavaScript Modules 这样的现代模块系统,使工具可以轻松构造完整的依赖图;

  • 服务 Workers,为后续的应用视图预缓存(“安装”)资源(进而支持离线优先架构)

  • 预加载,用于尽快交付所需资源。你还可以使用预加载链接头,这些头可以被协作服务器拦截并升级为 HTTP/2 Server Push(详情可见原文)。一定要记住,尽管 Push 功能强大,但它也面临着许多已知的挑战;不过 PRPL 使用服务 Worker 可以避免过度推送的问题(仅针对初始负载使用 push)。


如何实现 PRPL 模式?


PRPL 的很大一部分理念是对 JS 打包思维的颠覆,并在提供资源时拆分成尽可能接近编写资源时的粒度(至少拆分成独立的功能模块)。那么如何实现细粒度呢?


基于路由或基于组件的代码拆分和延迟加载


你正在将事物编写为组件。也许你正在使用 ES 模块。对于 Webpack,我们使用动态导入和代码拆分,将你的代码库拆分为按需加载的块。


Next.js 和 Nuxt.js 之类的元框架会默认实现基于路由的代码拆分。如果你使用的是 create-react-app 之类的工具链样板,则需要借助 React Router 之类的路由器进行动态导入,才能将基于路由或基于组件的代码拆分添加到你的应用程序中。


对于 PRPL 的 push/preload 部分,Webpack 还支持将 preload 作为魔术注释来预加载关键脚本。


预缓存


可以使用服务 worker 预缓存剩余的路由。另一种常见的做法是,利用 Workbox 之类的服务 worker 库来简化为应用程序预缓存路由和块的过程。


PRPL 使用何种应用程序结构?


PRPL 鼓励采用以下结构的单页应用(SPA)架构:


  • 从每个有效路由提供的应用程序的主入口点。

  • 这个文件应该很小,因为它将通过不同的 URL 提供,因此会被多次缓存。入口点中的所有资源 URL 都必须是绝对的,因为它可以从非顶级 URL 提供。

  • 外壳(app-shell),其中包括顶级应用逻辑、router 等。

  • 延迟加载的应用片段。

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


应用外壳骨架模式


应用应根据需要调用动态导入以延迟加载片段。例如,当用户更改为新路由时,它将导入与该路由关联的片段。这可能会向服务器发起新请求,或者只是从缓存中加载资源。


小结


除了针对 PWA 的基本目标和标准之外,PRPL 还尽量针对以下方面做了优化:


  • 尽量减少交互的准备工作——特别是在首次使用时(无论入口点如何)。

  • 尽量提升缓存效率,尤其是更新不断发布后的长期缓存效率。

  • 简化开发和部署。


自 2016 年诞生以来,PRPL 模式已获得了大规模使用,值得你在优化应用加载时考虑。


原文链接:https://addyosmani.com/blog/the-prpl-pattern/

2020-12-04 14:301896

评论

发布
暂无评论
发现更多内容

TimechoDB v1.3.1 发布 | 新增多种内置函数、脚本工具等功能,集群可观测性持续提升

Apache IoTDB

性价比拉满!英特尔锐炫新驱动,提升可达418%!

E科讯

Runaway Queries 管理:提升 TiDB 稳定性的智能引擎

PingCAP

MySQL 数据库 TiDB

代码检查入门

轶天下事

Alibaba Cloud Linux 解锁云算力-软硬协同构建云上最佳操作系统体验

OpenAnolis小助手

Java Linux 阿里云 操作系统 龙蜥社区

2024 年的第一次见面!这场开源数据技术沙龙不容错过

Apache IoTDB

NOW 闹个元宵?与亚信安慧AntDB一起猜灯谜,抽奖品

亚信AntDB数据库

数据库 AntDB AntDB数据库

ERC404 + meme 文化叙事,Dancing Beans 会达到怎样的高度?

股市老人

猜字谜|构建生成式 AI 应用实践(一)

亚马逊云科技 (Amazon Web Services)

互联网人的副业探索指南

老张

第二曲线 码农副业

HUAWEI Pocket 2亮相 HarmonyOS 4软硬件结合再掀智慧风潮

极客天地

蓝戟英特尔锐炫A770驱动对比测评,游戏性能迎来全面提升!

E科讯

数据价值在线化丨TiDB 在企查查数据中台的应用及 v7.1 版本升级体验

PingCAP

MySQL 数据库 开源 分布式 TiDB

TiDB 社区智慧合集丨TiDB 相关 SQL 脚本大全

PingCAP

MySQL 数据库 TiDB

记录 re:Invent 大会,使用 PartyRock 编写我们第一个 AI 应用以及心得

亚马逊云科技 (Amazon Web Services)

人工智能 API re:Invent 生成式人工智能

安擎科技携手华为云区块链共同打造安全天空

轶天下事

六大新兴技术助力未来工作效率提升

不在线第一只蜗牛

区块链 人工智能 云计算 物联网

【CodeArts开发者实践】CodeArts开发者八件套——开发者的进阶宝典!

轶天下事

华为云自主创新再迎成果:软件工具链为数字政府夯实研发新基建

轶天下事

想要了解华为IPD,先要了解需求如何管理!华为云CodeArts Req:支撑需求全生命周期管理,助力产研团队高效协作

轶天下事

PRPL模式加快Web应用加载_语言 & 开发_Addy Osmani_InfoQ精选文章