React Native 调试与性能治理
Flipper、Hermes、Systrace、列表优化、包体积与 New Architecture 下的性能排查路径。
Fabric 渲染器、TurboModule、JSI 直连、Hermes 引擎与 RN 性能治理的系统化方法。
RN 0.73 项目开启 New Architecture 后,冷启动 TTI 3.4s → 2.1s,列表 scroll 掉帧明显减少。代价是 2 个原生模块要重写 TurboModule Spec,以及 FlashList 要按 Fabric 文档调 estimatedItemSize。这篇是我们在生产启用 Fabric 的步骤与踩坑。
旧: JS ──JSON──▶ Native Module (异步)
新: JS ──JSI──▶ C++ TurboModule / Fabric (同步可批)
Fabric 统一布局与渲染;TurboModule 编译期生成类型安全接口。
# android/gradle.properties
newArchEnabled=true
# ios Podfile 同版本默认跟随 RCT_NEW_ARCH_ENABLED
cd ios && RCT_NEW_ARCH_ENABLED=1 pod install
常见 crash:
| 现象 | 原因 | 修复 |
|---|---|---|
红屏 TurboModuleRegistry.getEnforcing | 旧库未适配 | 升级或 patch |
| iOS Release 闪退 | Proguard / 错误 linking | 清 derivedData,查 autolinking |
| Android 白屏 | Hermes bytecode 不匹配 | ./gradlew clean |
| 场景 | 做法 | 我们数据 |
|---|---|---|
| 启动 | Hermes + 延迟非关键 native init | TTI -1.3s |
| 列表 | @shopify/flash-list + 固定 estimatedItemSize | 55→58fps |
| 图片 | react-native-fast-image | 内存 -20% |
| 动画 | Reanimated 3 worklet | JS 线程空闲 |
<FlashList
data={items}
estimatedItemSize={72}
renderItem={({ item }) => <Row item={item} />}
/>
// NativeLocalStorage.mm — Codegen 生成 Spec
@implementation NativeLocalStorage
- (NSString *)getItem:(NSString *)key {
return [[NSUserDefaults standardUserDefaults] stringForKey:key];
}
RCT_EXPORT_MODULE(NativeLocalStorage)
@end
旧 NativeModules.Xxx 逐步迁移;未迁移前 不要混用同步调用 假设。
团队 React 资产 + 原生模块多(蓝牙、打印)。Flutter 自绘一致性好,但 重写成本 6 人月+。新页面 RN,个别动画页考虑 Flutter module 嵌入——尚未落地。
Microsoft CodePush 维护模式变化后,我们改用 自建 OTA:签名 bundle + 差分:
nativeVersion >= x.yAppState listener、闭包持有 navigation、FastImage 缓存无上限useEffect(() => {
const sub = AppState.addEventListener('change', handler);
return () => sub.remove();
}, []);
RN 新架构不是开关一开就完事:Codegen 模块迁移、FlashList 配置、OTA 策略 要一起规划。先在非核心页灰度 newArchEnabled,指标达标再全量。