RN 常见性能问题:JS卡顿、UI卡顿、桥接通信耗时

RN(React Native)性能问题,基本可以归纳成三个核心方向:JS 卡顿、UI 卡顿、JS ↔ Native 桥接通信耗时。这三个问题经常互相影响,但排查思路并不一样。

1. JS 卡顿:JavaScript 线程忙不过来

RN 中大量业务逻辑运行在 JS Thread。如果 JS 线程长时间执行任务,就会出现:

  • 点击后很久才响应
  • 动画掉帧
  • FlatList 滑动不流畅
  • 手势响应延迟
  • setState 后 UI 更新迟缓
  • 定时器、Promise 回调堆积

典型问题:

c 复制代码
const result = hugeArray.map(item => {
  // 大量计算
  return heavyCalculate(item);
});

或者:

ini 复制代码
JSON.parse(largeJson);
JSON.stringify(hugeObject);

以及:

css 复制代码
for (let i = 0; i < 10000000; i++) {
  // CPU 密集型任务
}

核心原则:不要让 JS Thread 长时间同步执行重计算。

常见优化:

复制代码
重计算
 ↓
拆分任务
 ↓
减少计算量
 ↓
缓存结果
 ↓
避免无意义 render
 ↓
必要时交给 Native / JSI / Worklet

2. UI 卡顿:Native UI Thread 掉帧

UI 卡顿和 JS 卡顿不是一回事。

例如:

markdown 复制代码
JS Thread       正常
     ↓
UI Thread       忙于布局 / 绘制
     ↓
FPS ↓
     ↓
用户看到掉帧

常见原因:

① 页面组件太多

例如一个页面同时渲染几百个 View。

② FlatList 使用不当

ini 复制代码
<FlatList
  data={data}
  renderItem={renderItem}
/>

如果数据量很大,需要重点考虑:

ini 复制代码
<FlatList
  data={data}
  initialNumToRender={10}
  maxToRenderPerBatch={10}
  windowSize={5}
  removeClippedSubviews
/>

同时避免:

ini 复制代码
renderItem={() => <ComplexComponent />}

每次 render 都创建大量对象、函数或者复杂组件。

③ 图片太大

比如:

yaml 复制代码
原图 4000 × 3000
        ↓
RN 页面只显示 200 × 150
        ↓
仍然加载超大图片
        ↓
解码 + 内存 + GPU 压力

图片性能经常是移动端 UI 卡顿的隐藏杀手。


3. 桥接通信耗时:JS ↔ Native

这是 RN 早期架构中非常典型的问题。

传统架构可以简单理解成:

arduino 复制代码
JavaScript
    │
    │ Bridge
    ↓
Native
    │
    ↓
UI

如果 JS 和 Native 之间频繁传输大量数据:

arduino 复制代码
JS
 ↓
Bridge
 ↓
Native
 ↓
Bridge
 ↓
JS
 ↓
Bridge
 ↓
Native

就容易产生明显开销。

例如:

ini 复制代码
NativeModule.sendHugeData(largeObject);

如果 largeObject 非常大,而且调用频率很高,就可能造成性能问题。

尤其是这种模式:

scss 复制代码
for (...) {
  NativeModule.doSomething();
}

比:

ini 复制代码
NativeModule.doBatchSomething(data);

更容易产生通信开销。

核心原则:减少 JS ↔ Native 通信次数,同时减少传输数据量。


4. 新架构:Bridge 不再是唯一核心

现在 RN 性能优化不能只盯着传统 Bridge。

React Native 新架构主要涉及:

复制代码
JSI
Fabric
TurboModules
Hermes

可以简单理解:

arduino 复制代码
旧架构

JS
 │
Bridge
 │
Native

而新架构更加倾向于:

复制代码
JS
 │
JSI
 │
Native

因此一些过去严重依赖 Bridge 的性能问题,在新架构下会得到改善。

但这并不意味着:

"用了新架构,RN 就不会卡。"

实际上:

JS 重计算依然会卡。

Native UI 渲染压力依然会卡。

大量数据传递依然可能造成性能问题。

所以 RN 性能优化最终还是要回到:

markdown 复制代码
JS 性能
   +
React Render 性能
   +
UI / Layout 性能
   +
Native 性能
   +
通信性能
   +
内存
   +
图片

5. 面试/实际项目可以这样建立排查思路

遇到:

"RN 页面很卡"

不要直接开始改代码,而是先判断到底是谁卡了

markdown 复制代码
                 页面卡顿
                    │
          ┌─────────┴─────────┐
          ↓                   ↓
       JS 卡顿              UI 卡顿
          │                   │
   JS 是否长任务?       Layout 是否复杂?
   是否频繁 render?     图片是否过大?
   是否大量计算?       列表是否优化?
          │                   │
          └─────────┬─────────┘
                    ↓
              JS ↔ Native
                 是否频繁通信?
                    │
                    ↓
              内存 / 图片 / IO

一句话总结

问题 主要表现 优化方向
JS 卡顿 点击延迟、动画不响应 减少 JS 重计算、减少 render
UI 卡顿 掉帧、滑动不流畅 优化布局、列表、图片、绘制
桥接耗时 JS/Native 交互慢 减少通信次数和数据量
内存问题 页面越来越卡甚至崩溃 图片、缓存、组件生命周期
React Render 状态变化导致大量组件更新 memo、拆组件、状态下沉
列表性能 长列表 FPS 下降 FlatList/FlashList、虚拟化
新架构问题 某些 Native 模块性能异常 JSI、TurboModule、Fabric
相关推荐
JeffongTan4 小时前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
陆枫Larry6 小时前
Astro 是什么
前端
是立不是利8 小时前
写给设计师的 CSS 博客美学指南
前端·css
默_笙8 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师8 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端
kyriewen8 小时前
我手写了个极简版 React Router——才搞懂 v6 为什么砍了这么多 API
前端·javascript·程序员
a1117768 小时前
Shirone 二次元博客主题 开源
前端·开源
IT_陈寒9 小时前
Python的切片赋值把我坑惨了,这不是bug是特性
前端·人工智能·后端
掘金酱9 小时前
【社区公告】致每一位掘友:关于这次调整, 想再说几句
前端·人工智能
CoderLiu9 小时前
程序化工具调用(PTC)与动态工作流引擎:深入大模型工具调用的架构演进与实践
前端·人工智能·后端