优化的性能和以尽可能快的速度运行是导致移动应用程序成功的一些最重要因素。它们会极大地影响用户对应用的看法,并可能显著影响其 ROI。此外,表现良好的应用在 Google Play 商店中获得了更高的指标,从而提高了在店内搜索中的排名。在本文中,我们将向您展示如何在 Hermes 的帮助下实现所有这些好处。
使用 Hermes 实现更好的应用程序性能
问题:您在启动期间加载了大量 Android 软件包,这是不必要的。此外,您使用的是未针对移动设备优化的引擎。
用户希望应用程序能够响应迅速并快速加载。未能满足这些要求的应用程序最终可能会在 App Store 或 Play Store 中获得差评。在最极端的情况下,他们甚至可能被抛弃以支持他们的竞争对手。
启动时间没有单一的定义。这是因为加载阶段的许多不同阶段都会影响应用程序的 “快” 或 “慢” 感觉。例如,在 Lighthouse 报告中,有 8 个性能指标用于分析 Web 应用程序。其中之一是交互时间 (TTI),它测量应用程序准备好进行第一次交互之前的时间。
逐步加载过程
从您第一次从抽屉中按下应用程序图标的那一刻起,就会发生很多事情。
加载过程从本机初始化开始,该初始化加载 JavaScript VM 并初始化所有本机模块(上图中的 1)。然后,它继续从磁盘读取 JavaScript 并将其加载到内存中,解析并开始执行(上图中的 2)。
在下一步中,React Native 开始加载 React 组件并将最后一组指令发送到 UIManager(上图中的 3)。最后,UIManager 处理从 JavaScript 接收到的信息并开始执行本机指令,这将产生最终的本机接口(上图中的 4)。
如下图所示,有两组作会影响应用程序的整体启动时间。
第一个涉及前两个作(上图中的 1 和 2),并描述了 React Native 引导(启动 VM 和 VM 执行 JavaScript 代码)所需的时间。另一个作包括其余作(上图中的 3 和 4),并与您为应用程序创建的业务逻辑相关联。此组的长度在很大程度上取决于组件的数量和应用程序的整体复杂性。
本文重点介绍第一组 – 与您的配置相关的改进,而不是业务逻辑本身。如果您还没有测量应用程序的整体启动时间,或者还没有尝试过 Hermes 之类的东西,请继续阅读。
Android 上的启动时间长和用户体验缓慢可能是您的应用获得差评并最终被放弃的原因之一
创建有趣的应用程序非常重要,尤其是考虑到移动市场已经非常饱和。现在,所有移动应用程序不仅必须直观,而且还应该易于交互。
有一个常见的误解,即 React Native 应用程序与原生应用程序相比需要权衡性能。事实是,只要有足够的关注和配置调整,它们就可以同样快速地加载,而且没有任何相当大的差异。
如何使用 Hermes 提升应用的性能
虽然 React Native 应用程序负责本机接口,但它仍然需要在运行时运行 JavaScript 逻辑。为此,它分离了自己的 JavaScript 虚拟机。直到最近,它还使用 JavaScript – Core (JSC)。该引擎是 WebKit 的一部分,为 Safari 浏览器提供支持,默认情况下仅在 iOS 上可用。长期以来,React Native 使用 JSC 在 Android 上运行 JavaScript 也是有意义的。这是因为使用 V8 引擎(Chrome 附带的)可能会增加 Android 和 iOS 之间的差异,并使平台之间共享代码变得更加困难。
JavaScript 引擎需要执行各种复杂的作。他们不断提供新的启发式方法以提高整体性能,包括加载代码然后执行代码所需的时间。为此,他们对常见的 JavaScript作进行了基准测试,并对完成此过程所需的 CPU 和内存提出了挑战。
处理 JavaScript 引擎的开发人员的大部分工作都在最流行的网站(如 Facebook 或 X)上进行测试。React Native 使用 JavaScript 的方式不同也就不足为奇了。例如,为 Web 制作的 JavaScript 引擎不必太担心启动时间。浏览器很可能在加载页面时已经运行。因此,引擎可以将注意力转移到整体 CPU 和内存消耗上,因为 Web 应用程序可以执行许多复杂的作和计算,包括 3D 图形。
解决方案:开启 Hermes 以获得更好的性能
认识 Hermes - 一个专门为 React Native 设计的 JavaScript 引擎。 它针对移动设备进行了优化,并侧重于相对不敏感的 CPU 指标,例如应用程序大小和内存消耗。您可能已经在使用它了!从 v0.70 开始,React Native 默认开启了 Hermes,这标志着引擎稳定性的一个重要里程碑。
从 2019 年开源的仅限 Android 的基本引擎开始,它通过寻找小尺寸方法来添加更多 EcmaScript 规范功能(如代理和 Intl),直到可用于 macOS 和 iOS,它已经走过了漫长的道路。今天,Hermes 仍然足够小 (~2 MB),可以为应用程序的 TTI 提供重大改进,并为我们提供一组足够丰富的功能,可以在大多数应用程序中使用。
在我们详细讨论在现有 React Native 应用程序中启用 Hermes 之前,让我们先看一下它的一些关键架构决策。
Hermes 中的字节码预编译减少了执行业务逻辑的时间
通常,传统的 JavaScript VM 的工作原理是在运行时解析 JavaScript 源代码,然后生成字节码。因此,代码的执行会延迟到解析完成。Hermes就不一样了。为了减少引擎执行业务逻辑所需的时间,它会在构建期间生成字节码。
它可以花费更多时间使用各种技术优化捆绑包,使其更小、更高效。例如,生成的字节码的设计方式使其可以在 memory 中映射,而无需急于加载整个文件。优化该流程会带来显著的 TTI 改进,因为移动设备上的 I/O作往往会增加整体延迟。
Hermes 中没有 JIT 转化为 TTI 增加
与其他引擎不同,Hermes是 AOT(提前)引擎。这意味着整个 bundle 提前编译为字节码。因此,不存在 JIT 编译器对热代码段执行的某些优化。
一方面,它使 Hermes 捆绑包在面向 CPU 的基准测试中表现不佳。但是,这些基准并不能真正与现实生活中的移动应用程序体验相提并论,在现实生活中,TTI 和应用程序大小是优先考虑的。另一方面,JIT 引擎会降低 TTI,因为它们需要时间来解析捆绑包并及时执行它。他们也需要时间来“热身”。也就是说,他们必须运行代码几次才能检测常见模式并开始优化它们。
如何在 Android 和 iOS 上开始使用 Hermes
如果你想开始使用 Hermes,请确保将 android/app/build.gradle 中的 enableHermes 标志设置为 true:
project.ext.react = [
entryFile: "index.js",
enableHermes: true
]
对于 iOS,请在 ios/Podfile 中将 hermes_enabled 标志设置为 true:
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and
then install pods
:hermes_enabled => true
)
在这两种情况下,无论何时切换 Hermes 标志,请确保根据本机文件中提供的说明重新构建项目。重新构建项目后,您可以享受更快的应用程序启动时间,并且可能会更小的应用程序大小。
注意: 你可以在我们的博客上找到更多关于编译 Hermes 并将其与 React Native 集成的见解。如果你喜欢观看或收听,我们还有一整集专门针对 Hermes 的 The React Native Show 播客,所以一定要看看。
改进的启动时间意味着更好的性能和用户体验
使您的应用程序快速加载是一项持续的工作,其最终结果将取决于许多因素。您可以通过调整应用程序的配置和用于编译源代码的工具来控制其中的一些应用程序。
打开 Hermes 是您今天可以做的事情之一,可以大幅提高应用程序的某些性能指标,主要是 TTI。除此之外,您还可以查看 Meta 团队提供的其他重大改进。为此,请熟悉他们关于 React Native 性能的文章。它通常是一场微小而简单的改进的游戏,当一次应用时,一切都会有所不同。React Native 核心团队已经创建了一份关于股票 RN 和支持 Hermes 的 RN 之间基准测试的可视化报告,因此您可能想查看一下。
正如我们在关于运行最新 React Native 的文章中提到的,Hermes 是您可以利用的资产之一,只要您保持最新的 React Native 版本即可。这样做将帮助您的应用程序保持最佳性能,并使其以最大速度运行。
静态 Hermes 的未来(实验性)
在 React Native EU 2023 大会上,Hermes 首席工程师 Tzvetan Mikov 宣布了他的团队正在开发的一款代号为“Static Hermes”的实验工具。它推动了 Hermes 今天可以做的事情,即提前将类型化的 JavaScriptcode(本质上是 TypeScript 或 Flow)静态编译为本机汇编器指令的能力。它体现了你的应用不需要使用 Hermes 或任何其他 JavaScript 引擎来运行的想法,因为它已经包含了原生代码。这真是太疯狂了。
Static Hermes 是一项正在进行的实验,但是,您今天可以尝试一下。在 Hermes 的 GitHub 问题跟踪器上阅读更多内容:“如何试用静态 Hermes”。