跳到主要内容

iOS 性能优化专题

iOS 性能优化全攻略

1. 渲染性能

离屏渲染

  • 触发条件:圆角(masksToBounds)、阴影(shadow)、遮罩(mask)、光栅化
  • 代价:GPU 需额外开辟缓冲区,切换上下文耗性能
  • 优化:
    • 圆角 → 用图片遮罩或 Core Graphics 画圆角背景
    • 阴影 → 设置 shadowPath 避免实时计算
    • 静态内容 → shouldRasterize = true(开启缓存,但内存增加)

卡顿检测

  • CADisplayLink 监听帧率
  • Instruments → Core Animation 查看 FPS 和离屏渲染
  • RunLoop 观察者监测主线程超时(> 16ms 则记录堆栈)

2. 列表优化(UITableView / UICollectionView)

  • Cell 复用:必须使用 dequeueReusableCell
  • 高度缓存:计算后缓存 heightForRow,避免重复计算
  • 异步渲染:图片/富文本在子线程渲染,主线程只做展示(Texture/AsyncDisplayKit)
  • 预计算prefetchDataSource 在 cell 滚动到可视区前提前加载数据
  • 图片下载:SDWebImage / Kingfisher 自带磁盘+内存缓存

3. 启动优化

冷启动阶段

pre-main 阶段 (dyld)
→ 加载动态库(减少动态库数量,合并/静态化)
Rebase / Binding(减少 ObjC 元数据:类/方法/分类)
Initializer(+load 方法,改用 +initialize 或 dispatch_once)

main() 之后
→ didFinishLaunching(延迟/异步初始化三方 SDK
→ 首屏渲染
  • DYLD_PRINT_STATISTICS 测量 pre-main 耗时
  • 减少 +load 方法(每个都在启动时执行)
  • 二进制重排(Clang 插桩 + 收集 order 文件)减少 Page Fault

4. 内存优化

  • 图片内存:大图按需缩放,UIImage(named:) 会缓存,UIImage(contentsOfFile:) 不缓存
  • 循环引用排查:Instruments → Leaks / Allocations
  • autoreleasepool:循环处理大量对象时手动加 @autoreleasepool {}
  • NSCache:系统内存紧张时自动清理,比 NSMutableDictionary 更合适

5. 网络优化

  • HTTP/2:URLSession 默认支持,多路复用
  • 请求合并:批量接口减少请求次数
  • 图片格式:WebP / HEIF 替代 JPEG
  • 离线缓存:URLCache + ETag / Last-Modified 协商缓存
  • 压缩:Gzip / Brotli 压缩响应体

6. 包体积优化

  • 资源优化:Asset Catalog 压缩,移除未使用资源(LSUnusedResources)
  • 代码优化-dead_strip 删除未引用代码
  • 动态库转静态库:减少包体积和启动时间
  • On-Demand Resources:按需下载资源,减少初始包大小
  • App Thinning:Slicing(按设备分包)+ Bitcode

7. 高频面试题

  • 界面卡顿的本质? 主线程 RunLoop 一次循环超过 16.7ms,帧率低于 60fps
  • 为什么图片圆角会触发离屏渲染? 需要裁剪内容,必须在离屏缓冲区合成
  • Instruments 如何定位内存泄漏? Leaks 工具 → 查看泄漏对象 → Allocation 追踪引用链
  • 二进制重排原理? 通过收集启动期函数调用顺序写入 link map,让相关代码页相邻,减少 Page Fault