对我们的下一本书感兴趣?了解更多关于 使用 React 构建大型 JavaScript Web 应用

性能模式

PRPL 模式

让我们的应用程序在全球范围内访问可能是一个挑战!我们必须确保应用程序在低端设备和互联网连接不良的地区都能高效运行。为了确保我们的应用程序在困难条件下能够尽可能高效地加载,我们可以使用 PRPL 模式。

PRPL 模式侧重于四个主要的性能考虑因素

  • 有效地推送关键资源,这可以最大程度地减少到服务器的往返次数并缩短加载时间。
  • 尽快渲染初始路由,以改善用户体验
  • 在后台预缓存经常访问路由的资源,以最大程度地减少对服务器的请求次数并提供更好的离线体验
  • 延迟加载不经常请求的路由或资源

当我们想要访问一个网站时,我们首先需要向服务器发送请求以获取这些资源。入口点指向的文件从服务器返回,这通常是我们应用程序的初始 HTML 文件!浏览器 HTML 解析器在开始从服务器接收该数据后立即开始解析它。如果解析器发现需要更多资源,例如样式表或脚本,则会向服务器发送另一个 HTTP 请求以获取这些资源!

不得不反复请求资源并不理想,因为我们试图最大程度地减少客户端和服务器之间的往返次数!


很长一段时间,我们使用 HTTP/1.1 来进行客户端和服务器之间的通信。虽然 HTTP/1.1 相比 HTTP/1.0 引入了许多改进,例如能够在使用 keep-alive 标头发送新 HTTP 请求之前保持客户端和服务器之间的 TCP 连接存活,但仍然存在一些需要解决的问题!

HTTP/2 相比 HTTP/1.1 引入了重大的变化,这使得我们更容易优化客户端和服务器之间的消息交换。

而 HTTP/1.1 在请求和响应中使用换行符分隔的纯文本协议,HTTP/2 将请求和响应拆分为称为帧的更小的部分。包含标头和主体字段的 HTTP 请求至少被拆分为两个帧:一个标头帧和一个数据帧!

HTTP/1.1 在客户端和服务器之间最多有 6 个 TCP 连接。在通过同一个 TCP 连接发送新的请求之前,必须解决之前的请求!如果之前的请求需要很长时间才能解决,那么该请求会阻止其他请求发送。这个常见问题称为首行阻塞,可能会增加某些资源的加载时间!

HTTP/2 使用双向流,这使得能够建立包含多个双向流的单个 TCP 连接,这些流可以在客户端和服务器之间传递多个请求和响应帧!

一旦服务器收到了该特定请求的所有请求帧,它就会将它们重新组装并生成响应帧。这些响应帧被发送回客户端,客户端会将它们重新组装。由于流是双向的,我们可以在同一个流上发送请求和响应帧。

HTTP/2 通过允许在同一个 TCP 连接上发送多个请求(在之前的请求解决之前)来解决首行阻塞问题!


HTTP/2 还引入了一种更优化的获取数据的方法,称为服务器推送。服务器可以“推送”这些资源,而不是每次都通过发送 HTTP 请求明确地请求资源,服务器可以自动发送其他资源。

客户端收到其他资源后,这些资源将被存储在浏览器缓存中。当解析入口文件时发现这些资源时,浏览器可以快速从缓存中获取资源,而不必向服务器发送 HTTP 请求!

虽然推送资源减少了接收其他资源的时间,但服务器推送不了解 HTTP 缓存!推送的资源在下一次访问网站时不会对我们可用,并且必须再次请求。为了解决这个问题,PRPL 模式在初始加载后使用 服务工作者 来缓存这些资源,以确保客户端不会进行不必要的请求。


作为网站的作者,我们通常知道哪些资源需要尽早获取,而浏览器则尽力猜测这些资源。幸运的是,我们可以通过向关键资源添加 preload 资源提示来帮助浏览器!

通过告诉浏览器你想预加载某个资源,你是在告诉浏览器你希望比浏览器否则发现的更早获取它!预加载是优化加载对当前路由至关重要的资源所需时间的绝佳方法。

虽然预加载资源是减少往返次数和优化加载时间的绝佳方法,但推送太多文件可能会有害。浏览器的缓存是有限的,你可能会通过请求客户端实际上不需要的资源来不必要地使用带宽。


PRPL 模式侧重于优化初始加载。在初始路由完全加载和渲染之前,不会加载其他资源!

我们可以通过将我们的应用程序代码拆分为小型高效的捆绑包来实现这一点。这些捆绑包应该让用户能够只在需要的时候加载他们需要的资源,同时最大程度地提高可缓存性!

缓存较大的捆绑包可能是一个问题。可能会发生多个捆绑包共享相同的资源。

浏览器很难识别捆绑包中哪些部分是多个路由之间共享的,因此无法缓存这些资源。缓存资源对于减少到服务器的往返次数并使我们的应用程序脱机友好至关重要!

在使用 PRPL 模式时,我们需要确保我们请求的捆绑包包含我们当时所需的最小资源量,并且可以被浏览器缓存。在某些情况下,这可能意味着根本没有捆绑包会更高效,我们只需使用未捆绑的模块!

通过捆绑应用程序动态请求最小资源的优势可以通过配置浏览器和服务器来支持 HTTP/2 推送以及有效地缓存资源来轻松模拟。对于不支持 HTTP/2 服务器推送的浏览器,我们可以创建一个构建,该构建经过优化以最大程度地减少往返次数。客户端不需要知道它是否正在接收捆绑资源或未捆绑资源:服务器为每个浏览器提供适当的构建。


PRPL 模式通常使用应用程序外壳作为其主要入口点,这是一个包含大部分应用程序逻辑并由多个路由共享的最小文件!它还包含应用程序的路由器,该路由器可以动态请求必要的资源。

PRPL 模式确保在初始路由在用户设备上可见之前不会请求或渲染其他资源。初始路由成功加载后,可以安装服务器工作者以在后台获取其他经常访问路由的资源!

由于这些数据是在后台获取的,用户不会遇到任何延迟。如果用户想要导航到服务工作者已缓存的经常访问路由,服务工作者可以快速从缓存中获取所需资源,而不必向服务器发送请求。

可以动态导入不经常访问的路由的资源。