进阶 reactnative.dev 2026-10-11 06:04:21 · 30 阅读
第18章 React Native 实战:加速构建阶段的优化策略
版本:0.77 加速构建阶段
构建 React Native 应用可能开销巨大,会耗费开发者数分钟的时间。
随着项目增长,尤其是在拥有多名 React Native 开发者的较大组织中,这会成为一个问题。
为缓解这一性能损耗,本页提供了一些改进构建时间的建议。
开发期间仅构建一种 ABI(仅适用于 Android)
本地构建 Android 应用时,默认会构建全部 4 种 Application Binary Interface(ABI):armeabi-v7a、arm64-v8a、x86 和 x86_64。
然而,如果你在本地构建以测试模拟器或物理设备,通常不需要构建所有 ABI。
这将使原生构建时间减少约 75%。
如果使用 React Native CLI,可以在 run-android 命令中添加 --active-arch-only 标志。该标志确保从正在运行的模拟器或连接的电话中正确选择 ABI。要确认此方法正常工作,你会在控制台看到类似 info Detected architectures arm64-v8a 的消息。
$ yarn react-native run-android --active-arch-only
[ ... ]
info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 1037 file(s) to forward-jetify. Using 32 workers...
info JS server already running.
info Detected architectures arm64-v8a
info Installing the app...
这一机制依赖于 reactNativeArchitectures Gradle 属性。 因此,如果你直接通过命令行使用 Gradle 构建而不使用 CLI,可以按以下方式指定要构建的 ABI: $ ./gradlew :app:assembleDebug -PreactNativeArchitectures=x86,x86_64
如果你希望在 CI 上构建 Android 应用并使用矩阵并行构建不同架构,这会有所帮助。 如果愿意,你也可以在项目顶层文件夹中的 gradle.properties 文件里覆盖此值: # 使用此属性指定想要构建的架构。
# 你也可以通过 CLI 使用以下命令覆盖它
# ./gradlew -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
构建好应用的 Release 版本后,记得移除相关标志。你最终需要生成支持所有 ABI 的 APK 或 App Bundle,而不仅仅是适配日常开发中使用的单一 ABI。 使用编译器缓存 如果你经常进行原生构建(无论是 C++ 还是 Objective-C),使用编译器缓存会带来显著收益。 具体而言,有两种缓存可用:本地编译器缓存和分布式编译器缓存。 本地缓存 提示:以下指令同时适用于 Android 和 iOS。 如果只构建 Android 应用,直接沿用上述步骤即可。 如果同时也构建 iOS 应用,请参照下文“Xcode 特定配置”部分的说明。 建议通过 ccache 来缓存原生构建的编译过程。 Ccache 的工作原理是封装 C++ 编译器并存储编译结果;如果中间编译结果已有缓存,就会跳过重新编译。 Ccache 在大多数操作系统的包管理器中均可用。在 macOS 上,可通过 `brew install ccache` 安装。 或者,你可以按照官方安装说明从源码安装。 安装后,可以进行两次干净构建(例如在 Android 上,先运行 `yarn react-native run-android`,然后删除 `android/app/build` 文件夹,再次运行该命令)。你会注意到第二次构建比第一次快得多(耗时从几分钟缩短至几秒)。 构建过程中,可以运行 `ccache -s` 来验证 ccache 是否正常工作,并查看缓存命中率/未命中率: $ ccache -s
Summary:
Hits: 196 / 3068 (6.39 %)
Direct: 0 / 3068 (0.00 %)
Preprocessed: 196 / 3068 (6.39 %)
Misses: 2872
Direct: 3068
Preprocessed: 2872
Uncacheable: 1
Primary storage:
Hits: 196 / 6136 (3.19 %)
Misses: 5940
Cache size (GB): 0.60 / 20.00 (3.00 %)
注意,ccache 统计的是所有构建的累计数据。为了准确验证特定构建的缓存命中率,可以在构建前使用 `ccache --zero-stats` 重置统计数据。 如需清除缓存,可运行 `ccache --clear`。 Xcode 特定配置 为确保 ccache 在 iOS 和 Xcode 环境中正常工作,需要在 `ios/Podfile` 中启用 React Native 对 ccache 的支持。 在编辑器中打开 `ios/Podfile`,并取消 `ccache_enabled` 行的注释。 Ruby post_install do |installer|
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
# TODO: Uncomment the line below
:ccache_enabled => true
)
end
[ ... ]
info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 1037 file(s) to forward-jetify. Using 32 workers...
info JS server already running.
info Detected architectures arm64-v8a
info Installing the app...
这一机制依赖于 reactNativeArchitectures Gradle 属性。 因此,如果你直接通过命令行使用 Gradle 构建而不使用 CLI,可以按以下方式指定要构建的 ABI: $ ./gradlew :app:assembleDebug -PreactNativeArchitectures=x86,x86_64
如果你希望在 CI 上构建 Android 应用并使用矩阵并行构建不同架构,这会有所帮助。 如果愿意,你也可以在项目顶层文件夹中的 gradle.properties 文件里覆盖此值: # 使用此属性指定想要构建的架构。
# 你也可以通过 CLI 使用以下命令覆盖它
# ./gradlew
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
构建好应用的 Release 版本后,记得移除相关标志。你最终需要生成支持所有 ABI 的 APK 或 App Bundle,而不仅仅是适配日常开发中使用的单一 ABI。 使用编译器缓存 如果你经常进行原生构建(无论是 C++ 还是 Objective-C),使用编译器缓存会带来显著收益。 具体而言,有两种缓存可用:本地编译器缓存和分布式编译器缓存。 本地缓存 提示:以下指令同时适用于 Android 和 iOS。 如果只构建 Android 应用,直接沿用上述步骤即可。 如果同时也构建 iOS 应用,请参照下文“Xcode 特定配置”部分的说明。 建议通过 ccache 来缓存原生构建的编译过程。 Ccache 的工作原理是封装 C++ 编译器并存储编译结果;如果中间编译结果已有缓存,就会跳过重新编译。 Ccache 在大多数操作系统的包管理器中均可用。在 macOS 上,可通过 `brew install ccache` 安装。 或者,你可以按照官方安装说明从源码安装。 安装后,可以进行两次干净构建(例如在 Android 上,先运行 `yarn react-native run-android`,然后删除 `android/app/build` 文件夹,再次运行该命令)。你会注意到第二次构建比第一次快得多(耗时从几分钟缩短至几秒)。 构建过程中,可以运行 `ccache -s` 来验证 ccache 是否正常工作,并查看缓存命中率/未命中率: $ ccache -s
Summary:
Hits: 196 / 3068 (6.39 %)
Direct: 0 / 3068 (0.00 %)
Preprocessed: 196 / 3068 (6.39 %)
Misses: 2872
Direct: 3068
Preprocessed: 2872
Uncacheable: 1
Primary storage:
Hits: 196 / 6136 (3.19 %)
Misses: 5940
Cache size (GB): 0.60 / 20.00 (3.00 %)
注意,ccache 统计的是所有构建的累计数据。为了准确验证特定构建的缓存命中率,可以在构建前使用 `ccache --zero-stats` 重置统计数据。 如需清除缓存,可运行 `ccache --clear`。 Xcode 特定配置 为确保 ccache 在 iOS 和 Xcode 环境中正常工作,需要在 `ios/Podfile` 中启用 React Native 对 ccache 的支持。 在编辑器中打开 `ios/Podfile`,并取消 `ccache_enabled` 行的注释。 Ruby post_install do |installer|
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
# TODO: Uncomment the line below
:ccache_enabled => true
)
end
在 CI 上使用这种方式
Ccache 在 macOS 上会把缓存存储在 /Users/$USER/Library/Caches/ccache 文件夹中。
因此,你也可以在 CI 上保存和恢复这个文件夹来加速构建。但有几点需要注意:
- 在 CI 上,我们建议进行完整的干净构建,以避免缓存被污染的问题。如果你按照上一段提到的方法操作,应该可以把原生构建并行化到 4 个不同的 ABI 上,这样很可能就不需要在 CI 上使用 ccache 了。
- ccache 依赖时间戳来判断缓存是否命中。这在 CI 上效果不好,因为每次运行 CI 时文件都会重新下载。要解决这个问题,你需要使用 compiler_check content 选项,它改为通过对文件内容计算哈希值来判断。
分布式缓存
与本地缓存类似,你也可以考虑为原生构建使用分布式缓存。这对于频繁进行原生构建的大型组织尤其有用。
我们推荐使用 sccache 来实现这一点。具体的设置和使用方法,请参考 sccache 分布式编译快速入门文档。