🚀 React Native 常见性能瓶颈(深度版)
1️⃣ JS 线程阻塞(最常见 & 最致命)
📌 原因
React Native 的核心机制是:
- JS 线程负责业务逻辑
- 通过 Bridge(或 JSI)和原生通信
👉 一旦 JS 线程被阻塞:
- 页面无法响应点击
- 动画卡顿
- UI更新延迟
⚠️ 常见触发场景
- 大量同步计算(循环、排序、JSON处理)
- 复杂 setState / Redux 频繁更新
- 渲染大列表(未优化)
- 大量 console.log(开发环境尤其明显)
✅ 优化方案
- 使用 InteractionManager 延迟非关键任务
- 拆分计算逻辑(WebWorker思路 / 原生模块)
- 减少不必要的 state 更新
- 使用
useMemo / useCallback - 避免在 render 中做复杂计算
2️⃣ UI 渲染卡顿(掉帧)
📌 原因
UI线程负责绘制,如果:
- JS传输数据慢
- 或渲染组件过多
👉 就会导致掉帧(低于60FPS)
⚠️ 常见问题
- FlatList 未优化
- 大量嵌套 View
- 频繁 re-render
- 动画依赖 JS 线程
✅ 优化方案
🔹 列表优化(重点)
-
使用
FlatList/SectionList -
配置关键参数:
initialNumToRender maxToRenderPerBatch windowSize removeClippedSubviews
🔹 减少渲染
- 使用
React.memo - key 稳定
- 避免匿名函数
🔹 动画优化
- 使用
useNativeDriver: true - 或用更强方案:
👉react-native-reanimated
3️⃣ 内存泄漏(长期运行问题)
📌 原因
JS 和 Native 双端资源管理不当
⚠️ 常见泄漏点
- 定时器未清理(setInterval)
- 事件监听未移除
- 闭包引用大对象
- 图片资源未释放
- 页面卸载后仍 setState
✅ 优化方案
-
useEffect 清理:
useEffect(() => { const timer = setInterval(...) return () => clearInterval(timer) }, []) -
取消请求(axios cancel token)
-
移除监听(EventEmitter)
-
避免全局缓存滥用
4️⃣ 包体积过大(影响启动 & 下载)
📌 原因
- 图片资源过多
- 引入大型依赖库
- JS Bundle 未优化
⚠️ 影响
- 首次启动慢
- 安装包过大
- OTA 更新慢
✅ 优化方案
- 使用 Hermes 引擎
- 启用 Proguard / R8(Android)
- 图片压缩(WebP)
- 按需加载(动态 import)
- 删除无用依赖
5️⃣ Bridge 通信瓶颈(RN特有)
📌 原因
JS ↔ Native 通信是异步 + 序列化
👉 高频通信 = 性能灾难
⚠️ 场景
- 滚动事件频繁传递
- 动画依赖 JS
- 大数据传输
✅ 优化
- 减少通信次数
- 批量传输数据
- 使用 JSI / TurboModules / Fabric
- 动画走 Native(Reanimated)
6️⃣ 启动性能问题(冷启动慢)
📌 原因
- JS Bundle 过大
- 初始化逻辑太多
- 同步加载资源
✅ 优化方案
- 延迟初始化(Lazy load)
- 拆分 Bundle
- 使用 Hermes
- 启动页(Splash)优化体验
🧠 面试总结模板(可以直接背)
如果面试官问,你可以这样答:
👉 React Native 性能瓶颈主要包括:
- JS线程阻塞:大量计算或频繁更新导致页面卡顿
- UI渲染问题:组件过多或列表未优化导致掉帧
- 内存泄漏:定时器、监听、闭包未释放
- Bridge通信瓶颈:JS与Native频繁交互
- 包体积过大:影响启动和下载
- 启动性能问题:初始化逻辑过重
👉 对应优化手段包括:
- 列表优化(FlatList)
- 渲染优化(memo / hooks)
- 动画走 Native(Reanimated)
- 使用 Hermes
- 减少 Bridge 通信
- 做好资源释放