Skip to content
雲里
里雾

Hermes 字节码引擎

hermes 开发 更新于 2026/4/13

本页解释 Hermes 引擎以 AOT 字节码预编译换取移动端冷启动速度的设计取舍,对比开发模式与生产模式的行为差异,以及与 V8、JSC 的性能特性横向比较。

为什么需要 Hermes

移动端 JS 引擎面临一个桌面不存在的约束:冷启动时间。V8 和 JSC 在浏览器/桌面场景下对 JIT(Just-In-Time)编译做了大量优化——代码跑得快,但初始解析和编译本身需要时间和内存。

移动端 App 用户对启动时间极度敏感,而 JS 文件要在设备上从文本解析开始,对内存受限的手机来说代价很高。Hermes 的设计目标是:TTI(Time To Interactive)最优,而非峰值吞吐量最优


字节码预编译(.hbc)

Hermes 的核心设计:把”解析 + 编译”这个步骤从运行时移到构建时

传统流程(V8/JSC):
  bundle.js → [设备上] 解析文本 → AST → 字节码 → 执行

Hermes 流程:
  bundle.js → [构建机] hermesc 编译 → bundle.hbc → [设备上] 直接执行

.hbc 是 Hermes Bytecode 格式,设备不需要做任何解析,直接 mmap(内存映射)加载并执行。内存映射的好处是操作系统可以按需换页,不用一次性把整个 bundle 加载进 RAM。

Meta 在 2019 年公布的数据:Facebook App 的 TTI 从 4.3 秒降到 2.0 秒(降幅约 53%),内存占用下降约 3%,APK 体积下降约 12%(字节码比等效 JS 文本更紧凑)。


开发模式 vs 生产模式

Hermes 在两种模式下行为不同:

开发模式pnpm start / Expo Dev Client):

生产模式eas build / expo export):

这个差异意味着:在开发机上测量的启动时间不能代表真实用户体验,要测 TTI 必须用 Release build。


与其他引擎对比

特性HermesV8JSC
设计目标移动端 TTI峰值吞吐量Safari 兼容 + 通用
编译策略AOT 字节码JIT(TurboFan)JIT(FTL)
调试支持Chrome DevTools(via CDP)原生原生
React Native 支持官方默认(RN 0.64+)不支持旧版 RN 默认,iOS 仍可选
启动速度最快中等(JIT warm-up 开销)中等
长时运行性能略低(无 JIT 热优化)最高
内存占用中等

Hermes 的缺点:没有 JIT 意味着热代码路径(如高频循环)不会被优化,纯计算密集型场景下性能不如 V8。但 RN App 的性能瓶颈几乎从不在 JS 计算,而在 UI 渲染和网络——所以这个 trade-off 对移动端是合理的。


在 Expo SDK 54 中的位置

Expo SDK 54(RN 0.81)中 Hermes 是默认且唯一官方支持的引擎。app.json 里不需要任何配置,Hermes 已默认启用。

新架构(Fabric + TurboModules + JSI)要求 JS 引擎支持 JSI(JavaScript Interface)——一套 C++ API,允许原生代码直接持有 JS 值的引用,无需序列化。Hermes 完整支持 JSI,这是新架构能跑起来的基础之一。


面试视角

“Hermes 和 V8 有什么区别?为什么 RN 不用 V8?”

核心差异在设计目标:V8 为服务器/桌面的长时运行优化,Hermes 为移动端冷启动优化。Hermes 用 AOT 字节码换掉 JIT,牺牲了热路径峰值性能,换来极快的启动速度和低内存占用——这个 trade-off 在移动端场景是值得的。RN 团队曾评估过 V8(Android 上 V8 是系统内置的),但 bundle 的加载和解析开销在 V8 上依然存在,而 Hermes 通过 .hbc 消除了这个步骤。

参见

参考

版本说明