Appearance
01 - 性能优化深度
目录
1. 性能优化体系与指标
iOS 性能优化体系:
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ 性能优化的核心指标: │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 指标 │ 目标值 │ 影响 │ │
│ ├──────────────────────────────────────────────────────────────┤ │
│ │ 启动时间 │ < 2s(冷启动) │ 用户体验 │ │
│ │ 帧率 │ 60fps(核心场景 55+fps) │ 流畅度 │ │
│ │ 内存占用 │ < 200MB(现代设备) │ 稳定性 │ │
│ │ CPU 使用率 │ < 80%(峰值不超过 90%) │ 流畅度 │ │
│ │ 网络延迟 │ < 100ms(API 响应) │ 响应速度 │ │
│ │ 电池消耗 │ < 10%/h(重度使用) │ 续航 │ │
│ │ APK/APP 大小 │ < 50MB(不含图片) │ 下载率 │ │
│ │ 内存泄漏 │ 0 泄漏 │ 稳定性 │ │
│ │ 崩溃率 │ < 0.1% │ 稳定性 │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ 性能优化分层: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Layer 1: 启动优化 │
│ │ Layer 2: UI/渲染性能 │
│ │ Layer 3: 网络性能 │
│ │ Layer 4: 内存管理 │
│ │ Layer 5: 电池优化 │
│ │ Layer 6: 存储性能 │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 性能优化原则: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ • 先测量后优化(测量 > 猜测) │
│ │ • 优化优先级:启动 > UI > 网络 > 内存 > 电池 │
│ │ • 减少不必要的工作 │
│ │ • 利用系统 API 和底层优化 │
│ │ • 异步处理阻塞操作 │
│ │ • 缓存热点数据 │
│ │ • 减少主线程工作量 │
│ │ • 批量处理减少 IO 次数 │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
*/2. 启动优化
启动优化深度分析:
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ 启动优化的核心: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ // 冷启动时间分解 │
│ │ // 0-100ms: dyld 加载 + 链接 │
│ │ // 100-300ms: +0, +1, +2 阶段初始化 │
│ │ // 300-500ms: main 函数 + 应用生命周期 │
│ │ // 500ms+: 首屏渲染 + 数据加载 │
│ │ │
│ │ 启动优化策略: │
│ │ • 延迟初始化(非关键功能) │
│ │ • 减少 dyld 链接时间(预编译头、减少依赖) │
│ │ • 减少 -init 初始化函数 │
│ │ • 使用 MRC/MVVM 减少控制器初始化 │
│ │ • 主线程异步化 │
│ │ • 图片懒加载 │
│ │ • JSON 预编译 │
│ │ • 启动画面(LaunchScreen) │
│ │ │
│ │ dyld 优化: │
│ │ • 减少动态库数量(合并 framework) │
│ │ • 使用静态库或 xcframework(消除 dyld 链接) │
│ │ • 预编译头(PCH)减少编译时间 │
│ │ • 使用 bitcode(减少符号链接时间) │
│ │ │
│ │ -init 优化: │
│ │ • 减少 @autoreleasepool 中的初始化 │
│ │ • 延迟加载不需要的类 │
│ │ • 使用 dispatch_once 确保单次初始化 │
│ │ │
│ │ 启动优化测量: │
│ │ • Instruments(Time Profiler) │
│ │ • NSLog 手动计时 │
│ │ • 启动指标(DYLD_STATS、NSTimeInterval) │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 冷启动 vs 热启动: │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 指标 │ 冷启动 │ 热启动 │ │
│ │ ├──────┬──────────────────────────────┼──────────────────────┤ │
│ │ │ dyld │ ✅ 加载 + 链接 │ ❌ 跳过 │ │
│ │ │ 启动时间 │ 2-5s(普通) │ 0.5-2s │ │
│ │ │ 优化 │ dyld 优化 + 延迟初始化 │ 预加载 + 缓存 │ │
│ │ │ 主线程 │ 减少主线程工作 │ 减少重复初始化 │ │
│ │ └─────┴──────────────────────────────┴──────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 启动优化总结: │
│ • dyld:减少动态库、合并 framework │
│ • -init:减少初始化函数、延迟加载 │
│ • 主线程:减少主线程工作、异步化 │
│ • 预编译:PCH、bitcode │
│ • 启动画面:使用 LaunchScreen │
│ • 测量:Instruments + NSLog 手动计时 │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
*/3. UI/渲染性能
UI/渲染性能深度分析:
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ 渲染原理: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ // iOS 渲染管线 │
│ │ // 1. Layout(布局计算) │
│ │ // 2. Rasterization(光栅化) │
│ │ // 3. Core Animation(合成) │
│ │ // 4. Display List(绘制指令) │
│ │ // 5. GPU(渲染到屏幕) │
│ │ │
│ │ 帧率计算: │
│ │ • 60fps = 16.67ms/frame │
│ │ • 120fps = 8.33ms/frame │
│ │ • 每帧可用时间:< Layout + Raster + Core Animation + GPU │
│ │ │
│ │ 渲染性能优化: │
│ │ • 减少 layout 计算(缓存布局、预计算) │
│ │ • 减少光栅化(减少透明视图、使用 opaque) │
│ │ • 减少合成层数量(减少 CALayer) │
│ │ • 减少绘制指令(使用 drawRect 缓存) │
│ │ • GPU 优化(使用纹理、减少颜色空间转换) │
│ │ • 异步计算(非主线程计算布局) │
│ │ • 减少 sublayer 数量 │
│ │ • 使用 isOpaque 标记不透明视图 │
│ │ • 使用 shouldRasterize 缓存光栅化 │
│ │ • 避免频繁的 CATransaction │
│ │ │
│ │ Layout 优化: │
│ │ • 避免在 draw 阶段调用 layoutIfNeeded │
│ │ • 减少 layoutSubviews 调用 │
│ │ • 缓存 layout 结果 │
│ │ • 使用 Auto Layout 替代手动 layout │
│ │ │
│ │ Rasterization 优化: │
│ │ • 使用 opaque 视图减少光栅化 │
│ │ • 减少透明视图 │
│ │ • 使用 shouldRasterize 缓存光栅化(慎用) │
│ │ │
│ │ Core Animation 优化: │
│ │ • 减少 CALayer 数量 │
│ │ • 使用 CATransaction 减少重绘 │
│ │ • 避免频繁设置 frame/bounds │
│ │ • 使用 animation 而非逐帧更新 │
│ │ │
│ │ GPU 优化: │
│ │ • 使用纹理而非逐像素绘制 │
│ │ • 减少颜色空间转换 │
│ │ • 使用 CGImage 而非 UIImage(减少转换) │
│ │ • 使用 UIGraphicsImageRenderer(高效渲染) │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 滚动性能优化: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ • 减少 cell 布局计算 │
│ │ • 预取数据(UITableView/UICollectionView prefetch) │
│ │ • 减少子视图数量 │
│ │ • 使用 shouldRasterize 缓存复杂 cell │
│ │ • 异步绘制复杂内容 │
│ │ • 使用 diffable data source 减少重绘 │
│ │ • 延迟加载图片(图片异步加载) │
│ │ • 减少 tableview 行高计算(预估行高) │
│ │ • 使用 UITableView / UICollectionView 的原生优化 │
│ │ │
│ │ UITableView 优化: │
│ │ • registerNib/registerClass(预注册 cell) │
│ │ • estimatedRowHeight(预估行高) │
│ │ • prefetchDataSource(预取数据) │
│ │ • reloadItems 替代 reloadRows(局部刷新) │
│ │ │
│ │ UICollectionView 优化: │
│ │ • diffable data source(高效数据源) │
│ │ • prefetchDataSource(预取数据) │
│ │ • minimumLineSpacing(减少间距计算) │
│ │ • layout.invalidateLayout(避免全量刷新) │
│ │ • prefetchingEnabled(预取) │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ UI/渲染性能总结: │
│ • 减少 layout 计算(缓存、预计算) │
│ • 减少光栅化(opaque、减少透明) │
│ • 减少合成层(减少 CALayer 数量) │
│ • 减少绘制指令(drawRect 缓存) │
│ • GPU 优化(纹理、颜色空间) │
│ • 异步计算(非主线程处理) │
│ • 滚动优化(cell、预取、diffable data source) │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
*/4. 网络性能优化
网络性能优化深度分析:
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ 网络优化核心: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ // 网络优化策略 │
│ │ • 减少请求数量(合并请求、批量接口) │
│ │ • 减少数据量(压缩、增量更新、分页) │
│ │ • 缓存策略(内存、磁盘、网络缓存) │
│ │ • 连接优化(HTTP/2、Keep-Alive) │
│ │ • 超时重试(指数退避、熔断) │
│ │ • 并行请求(并发控制、优先级) │
│ │ • CDN 加速(静态资源) │
│ │ • 协议选择(HTTP/2 > HTTP/1.1 > HTTPS > HTTP) │
│ │ │
│ │ URLSession 优化: │
│ │ • 使用 URLSessionConfiguration(持久化连接) │
│ │ • 设置 timeoutInterval(15-30s) │
│ │ • 使用 background session(后台传输) │
│ │ • 设置 httpAdditionalHeaders(减少请求头) │
│ │ • 使用 URLCache(自动缓存) │
│ │ • 设置 queuePriority(优先级控制) │
│ │ • 使用 concurrentRequestsLimit(并发限制) │
│ │ │
│ │ 网络优化策略: │
│ │ • 合并请求:减少 HTTP 连接次数 │
│ │ • 数据压缩:Gzip/Brotli 压缩 │
│ │ • 增量更新:只获取变更数据 │
│ │ • 分页加载:减少单次数据量 │
│ │ • CDN 加速:静态资源 CDN 分发 │
│ │ • HTTP/2:多路复用、头部压缩 │
│ │ • Keep-Alive:复用 TCP 连接 │
│ │ • 重试策略:指数退避(1s, 2s, 4s, 8s, 16s) │
│ │ • 熔断机制:连续失败后暂停请求 │
│ │ │
│ │ 网络性能指标: │
│ │ • 首字节时间(TTFB):< 200ms │
│ │ • 完全加载时间(FLT):< 3s │
│ │ • 带宽利用率:< 80%(避免网络拥塞) │
│ │ • 连接复用率:> 80%(Keep-Alive 命中) │
│ │ • 缓存命中率:> 60%(减少网络请求) │
│ │ • 失败率:< 1%(重试策略有效性) │
│ │ │
│ │ 网络优化方案对比: │
│ │ ┌───┬───────┬───────┬───────┬───────┬───────┬───────┐ │
│ │ │ 方案 │ TTFB │ 带宽 │ 连接 │ 缓存 │ 重试 │ 优先级 │ │
│ │ ├─┼───────┼───────┼───────┼───────┼───────┼───────┤ │
│ │ │ 合并 │ ↓ │ ↓ │ ↓ │ ⚠️ │ ⚠️ │ ⚠️ │ │
│ │ │ 压缩 │ ⚠️ │ ↓↓↓ │ ↓ │ ⚠️ │ ⚠️ │ ⚠️ │ │
│ │ │ 缓存 │ ↓↓↓ │ ⚠️ │ ↓ │ ↑↑↑ │ ⚠️ │ ⚠️ │ │
│ │ │ CDN │ ↓↓↓ │ ↓ │ ↓ │ ⚠️ │ ⚠️ │ ⚠️ │ │
│ │ │ HTTP/2 │ ↓↓ │ ⚠️ │ ↓ │ ⚠️ │ ⚠️ │ ⚠️ │ │
│ │ │ 重试 │ ⚠️ │ ⚠️ │ ↑ │ ⚠️ │ ↑↑↑ │ ⚠️ │ │
│ │ └───┴───────┴───────┴───────┴───────┴───────┴───────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 网络性能优化总结: │
│ • 减少请求(合并、批量) │
│ • 减少数据(压缩、分页) │
│ • 缓存(内存、磁盘、网络缓存) │
│ • 连接优化(HTTP/2、Keep-Alive) │
│ • 超时重试(指数退避、熔断) │
│ • CDN 加速(静态资源) │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
*/5. 内存与电池优化
内存与电池优化深度分析:
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ 内存优化: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ • 减少对象创建(对象池、重用) │
│ │ • 减少内存分配(预分配、批量操作) │
│ │ • 减少内存碎片(紧凑存储、对齐) │
│ │ • 减少内存占用(更小的类型、压缩) │
│ │ • 减少内存泄漏(weak、unowned、闭包捕获) │
│ │ • 减少内存峰值(异步处理、分批处理) │
│ │ │
│ │ 内存优化技巧: │
│ │ • 使用 CFDataRef 替代 NSData(减少桥接) │
│ │ • 使用 NSMutableData 替代多次创建 Data │
│ │ • 使用 NSMutableString 替代多次创建 String │
│ │ • 使用预分配数组(repeating count) │
│ │ • 使用 LazySequence 延迟计算 │
│ │ • 使用 NSCache(自动管理内存) │
│ │ • 使用 URLCache(自动管理网络缓存) │
│ │ │
│ │ 内存优化指标: │
│ │ • 内存占用:< 200MB(现代设备) │
│ │ • 内存增长:< 10MB/min(无泄漏) │
│ │ • 内存峰值:< 300MB(安全线) │
│ │ • 泄漏检测:0 泄漏 │
│ │ │
│ │ 电池优化: │
│ │ • 减少定位频率(use显著位置变更代替持续定位) │
│ │ • 减少网络请求(合并请求、缓存) │
│ │ • 减少 GPS 使用(使用 WiFi/基站定位) │
│ │ • 使用 backgroundTasks(批量处理) │
│ │ • 减少动画频率(减少 RunLoop 迭代) │
│ │ • 使用 CoreLocation 的 kCLLocationAccuracyBestForNavigation │
│ │ • 使用 CLSignificantLocationChangeMonitoring │
│ │ • 使用 CMMotionActivityManager(运动感知) │
│ │ │
│ │ 电池优化指标: │
│ │ • 重度使用:< 10%/h │
│ │ • 轻度使用:< 3%/h │
│ │ • 待机:< 1%/h │
│ │ • 后台任务:< 10min(iOS 限制) │
│ │ │
│ │ 内存 vs 电池优化对比: │
│ │ ┌───┬───────┬───────┬───────┬───────┬───────┬───────┐ │
│ │ │ 策略 │ 内存 │ 电池 │ 网络 │ CPU │ 磁盘 │ 用户体验 │ │
│ │ ├─┼───────┼───────┼───────┼───────┼───────┼───────┤ │
│ │ │ 缓存 │ ↓↑ │ ↓ │ ↓↓↓ │ ⚠️ │ ↑ │ ↑ │ │
│ │ │ 异步 │ ↓ │ ↓ │ ↓ │ ↓ │ ↑ │ ↓ │ │
│ │ │ 压缩 │ ↓ │ ↓ │ ↓↓↓ │ ↑ │ ⚠️ │ ⚠️ │ │
│ │ │ 减少对象 │ ↓↓↓ │ ↓ │ ⚠️ │ ↓ │ ⚠️ │ ↑ │ │
│ │ │ 合并请求 │ ⚠️ │ ↓ │ ↓↓↓ │ ⚠️ │ ⚠️ │ ↓ │ │
│ │ └───┴───────┴───────┴───────┴───────┴───────┴───────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 内存与电池优化总结: │
│ • 减少对象创建和内存分配 │
│ • 使用缓存减少重复计算 │
│ • 异步处理减少 CPU 压力 │
│ • 减少网络请求和 GPS 使用 │
│ • 合并请求、压缩数据 │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
*/6. 分析工具
性能分析工具深度分析:
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ 分析工具对比: │
│ ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┐ │
│ │ 工具 │ 用途 │ 精度 │ 难度 │ 适用场景 │ 免费 │ 推荐 │ │
│ ├─┼───────┼───────┼───────┼───────┼───────┼───────┤ │
│ │Instruments│ 全面 │ 高 │ 中 │ 生产环境 │ ✅ │ ✅ 首选 │ │
│ │Time Profiler│ CPU │ 高 │ 低 │ CPU 分析 │ ✅ │ ✅ │ │
│ │Leaks │ 内存 │ 高 │ 中 │ 内存泄漏 │ ✅ │ ✅ │ │
│ │Allocations │ 内存 │ 高 │ 中 │ 内存分配 │ ✅ │ ✅ │ │
│ │Core Animation│ 渲染│ 高 │ 低 │ 渲染性能 │ ✅ │ ✅ │ │
│ │Address Sanitizer│ 内存│ 高 │ 高 │ 内存错误 │ ✅ │ ✅ │ │
│ │Xcode Memory Graph│ 内存│ 中 │ 低 │ 内存图 │ ✅ │ ✅ │ │
│ │WWDC 2020 │ 启动 │ 中 │ 中 │ 启动优化 │ ✅ │ ✅ │ │
│ └───────┴───────┴───────┴───────┴───────┴───────┴───────┘ │
│ │
│ Instruments 使用: │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ // 1. 打开 Instruments │
│ │ // Xcode → Product → Profile │
│ │ │
│ │ // 2. 选择模板 │
│ │ // • Allocations — 内存分配 │
│ │ // • Leaks — 内存泄漏 │
│ │ // • Time Profiler — CPU 分析 │
│ │ // • Core Animation — 渲染性能 │
│ │ // • Network — 网络性能 │
│ │ // • Energy Diagnostics — 电池 │
│ │ │
│ │ // 3. 记录和分析 │
│ │ // • 模拟用户操作 │
│ │ // • 观察内存/CPU/网络指标 │
│ │ // • 识别热点和异常 │
│ │ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ 性能分析工具总结: │
│ • Instruments:全面性能分析(首选) │
│ • Allocations/Leaks:内存分析 │
│ • Time Profiler:CPU 分析 │
│ • Core Animation:渲染性能分析 │
│ • Address Sanitizer:内存错误检测 │
│ • Xcode Memory Graph:内存图 │
│ • WWDC 2020:启动优化 │
│ │
└───────────────────────────────────────────────────────────────────────────────────┘
*/7. 面试考点汇总
高频面试题
Q1: iOS 启动优化策略?
答:
- dyld 优化:减少动态库、合并 framework、预编译头
- -init 优化:减少初始化函数、延迟加载
- 主线程优化:减少主线程工作、异步处理
- 启动画面:使用 LaunchScreen
- 测量:Instruments + NSLog 手动计时
Q2: UI 渲染性能优化策略?
答:
- 减少 layout 计算(缓存、预计算)
- 减少光栅化(opaque、减少透明视图)
- 减少合成层数量(减少 CALayer)
- 减少绘制指令(drawRect 缓存)
- GPU 优化(纹理、颜色空间)
- 异步计算(非主线程处理)
- 滚动优化(cell、预取、diffable data source)
Q3: 网络性能优化策略?
答:
- 减少请求(合并、批量)
- 减少数据(压缩、分页)
- 缓存(内存、磁盘、网络缓存)
- 连接优化(HTTP/2、Keep-Alive)
- CDN 加速(静态资源)
- 重试策略(指数退避、熔断)
Q4: 内存优化策略?
答:
- 减少对象创建(对象池、重用)
- 减少内存分配(预分配、批量操作)
- 减少内存碎片(紧凑存储、对齐)
- 使用更小的类型(Int32 vs Int64)
- 减少内存泄漏(weak、unowned、闭包捕获)
- 异步处理减少峰值
Q5: 性能分析工具?
答:
- Instruments(Allocations/Leaks/Time Profiler/Core Animation/Network)
- Address Sanitizer(内存错误)
- Xcode Memory Graph(内存图)
- WWDC 2020(启动优化)