本文目录导读:

- 核心原则:找出瓶颈
- 通用优化策略(跨平台)
- 平台特定优化(Android / iOS)
- 跨平台框架优化(Flutter / React Native)
- 速查 Checklist(排查步骤)
- 终极武器:性能分析工具
移动端应用卡顿是一个常见的性能问题,通常由主线程阻塞、内存泄漏、过度绘制或渲染性能差引起,优化需要系统性地从渲染、内存、计算、资源四个维度入手。
以下是针对移动端(iOS/Android/Flutter/React Native)通用的优化策略,以及具体平台和语言的针对性建议。
核心原则:找出瓶颈
不要盲目优化,先测量,再优化。
- 工具: Android Studio Profiler / Xcode Instruments / Chrome DevTools(用于RN/Flutter)。
- 关键指标: FPS(帧率)、页面渲染时间、CPU占用率、内存占用、GC(垃圾回收)频率。
通用优化策略(跨平台)
渲染优化(解决掉帧、慢启动)
- 减少布局层级:避免嵌套过深的 LinearLayout/Stack/Column。
- 异步渲染:对于复杂页面,使用懒加载或异步渲染框架。
- 避免过度绘制:
- Android:开启“显示过度绘制区域”调试,减少不必要的背景层。
- iOS:避免透明层叠加(
opaque = true)。
- 使用硬件加速:确保启用了硬件加速(默认通常启用),避免大量使用
Canvas非硬件加速路径。
计算优化(解决操作响应慢、卡顿)
- 主线程轻量化:
- 绝对不要在UI线程(即主线程)做网络请求、大文件读写、复杂JSON解析。
- 图片解码、数据库查询都应在子线程进行。
- 避免高耗时操作:避免在
onScroll、OnLayout等频繁回调中执行复杂计算。
内存优化(解决GC卡顿、OOM)
- 内存泄漏:这是卡顿的主要原因之一,检查Activity/Fragment/ViewController的引用链(使用LeakCanary/Instruments)。
- 大对象复用:复用Bitmap、复杂View、Dialog。
- 图片压缩:加载图片前解码为合适尺寸(
ImageLoader的resize),使用WebP格式(比PNG小,解码快)。 - 对象池:频繁创建销毁的对象(如消息、粒子)使用对象池。
资源与IO优化
- 图片加载:使用三级缓存(内存->磁盘->网络)库 (Glide/Picasso/SDWebImage/Kingfisher)。
- 数据库:使用批量写、异步写(如Room/Realm/WCDB),避免在主线程访问。
- 动画:优先使用
Animator/UIViewAnimation而非Timer循环刷新;使用Property Animation替代帧动画。
平台特定优化(Android / iOS)
Android 专项
- UI线程瓶颈
- 检查点:
Systrace查看主线程长时间Layout/Invalidate。 - 优化:使用
ConstraintLayout减少嵌套;将RecyclerView的OnBindViewHolder中的逻辑尽量轻量化。
- 检查点:
- 内存与GC
- 检查点:
Allocation Tracker查看大量临时对象。 - 优化:将局部变量声明在循环外;避免在
getView/onBindViewHolder中创建对象。
- 检查点:
- GPU过度绘制
- 检查点:开启开发者选项 -> 监控 -> 调试GPU过度绘制。
- 优化:移除
windowBackground、ListSelector等冗余背景,使用merge标签合并布局。
- XML布局性能:使用
include/merge/ViewStub。
iOS 专项
- RunLoop模式:阻塞主线程(如图片解码)会导致卡顿,将耗时的图片解码放到后台线程。
- 显示层级(Layer)
- 离屏渲染:这是iOS卡顿的头号敌人,避免同时使用
cornerRadius+clipsToBounds+shadow+maskToBounds。 - 优化:使用
CAShapeLayer绘制圆角;使用shadowPath;或使用图片蒙版。
- 离屏渲染:这是iOS卡顿的头号敌人,避免同时使用
- 自动布局 (Auto Layout):对性能敏感的页面(如滚动列表),尽量使用 Frame 布局。
- 内存警告:
didReceiveMemoryWarning是强信号,释放缓存图片和可重建的视图。
跨平台框架优化(Flutter / React Native)
Flutter 优化
Flutter 的卡顿通常由 Dart 主 Isolate 阻塞或 Widget 树重建导致。
- 避免 Build 太多:使用
const构造函数标记不变的小部件,RepaintBoundary隔离重绘区域。 - 列表性能:使用
ListView.builder或GridView.builder(懒加载),避免在itemBuilder中做复杂计算。 - 图片缓存:使用
cached_network_image包。 - 纹理/Platform View:避免在滚动列表中频繁嵌入原生平台视图(
AndroidView/UiKitView)。
React Native (RN) 优化
RN 的卡顿通常由 JS 线程阻塞 或 Bridge 通信慢 导致。
- 使用 Hermes 引擎:Hermes 是专为 RN 优化的 JS 引擎,启动更快、内存更小。
- 列表性能:使用
FlatList/SectionList代替ScrollView。- 设置
getItemLayout(提高滚动性能)、removeClippedSubviews。 - 避免在
renderItem中做高开销计算。
- 设置
- 避免内联函数:每次渲染都会创建新引用,导致子组件不必要重渲染。
- 使用
InteractionManager:将动画/导航后的非关键任务延迟执行。
速查 Checklist(排查步骤)
- 启动卡顿:检查Splash页是否有大图片直接解码在主线程;检查三方SDK初始化是否太多。
- 列表滑动卡顿:
- 检查
getView/renderItem中是否有网络/文件IO。 - 检查图片是否未加载缩略图(加载原图)。
- 检查是否有过度绘制或离屏渲染。
- 检查是否每帧都在动态计算高度。
- 检查
- 动画卡顿:
- 检查动画回调中是否做了复杂逻辑。
- 检查是否有高内存泄漏导致GC频繁。
- iOS:检查是否有离屏渲染(圆角+阴影+mask)。
- 随机闪退/卡顿:
- 检查网络请求回调是否切换到了主线程做大量数据处理。
- 检查大JSON解析是否在主线程。
终极武器:性能分析工具
| 工具 | 平台 | 作用 |
|---|---|---|
| Android Profiler | Android | CPU/内存/网络/GPU概览 |
| Systrace | Android | 主线程精确事件追踪 |
| LeakCanary | Android | 自动检测内存泄漏 |
| Instruments | iOS | Time Profiler / Allocations / Leaks |
| Xcode Debug Navigator | iOS | FPS显示 |
| Flutter DevTools | Flutter | 帧率/Dart内存/Widget树 |
| React DevTools / Flipper | RN | Profiler / FPS |
优化移动端卡顿的最好方法是先用工具定位问题,而非大范围重写代码,核心原则始终是:
- 主线程只跑UI:把网络、数据库、图片解码都扔到子线程。
- 避免隐藏的昂贵操作:如过度绘制、离屏渲染、内存泄漏导致GC。
- 高效绘制:减少布局层级,使用懒加载列表,算法复用。
单条黄金建议:如果你只能做一件事来优化卡顿,先解决内存泄漏(尤其是Activity/ViewController泄漏)和图片解码(特别是列表中加载大图),这两项解决了80%的卡顿问题。