APP终极性能生存指南

性能是客户端永远绕不开的话题,一起来康康今年的WWDC提供了哪些有关性能提升的建议吧~

(温馨提示:本片内容来源自WWDC21:Ultimate application performance survival guide

想了解更多WWDC2021内容的小伙伴,可以阅读我以下文章,欢迎多多交流和指正

检测和诊断内存问题

一文带你读完WWDC21核心(新)技术点

  • 使用的五种工具

    • Xcode Organizer
    • MetricKit
    • Instruments
    • XCTest
    • App Store Connect API
  • 参考的八个性能指标

    2.png

    • 电量

    • 启动时间

    • 超时响应率(Hang rate)

      APP无法响应用户的输入或者行为超过250ms,即记作一个hang

    • 内存

    • 磁盘写入

    • 滚动卡顿

    • APP终止

    • MXSignposts

  • 电量(battery usage)

    • 优化电池使用需要关注的几点:

      • CPU
      • 网络
      • 定位
      • 音频
      • 蓝牙
      • GPU

      其中CPU、网络、定位是电量消耗大户

    • 使用Xcode工具查看Debug期间的电量损耗情况

      4.png

      • 查看CPU超过20%的阶段(CPU High Utilization)
      • 查看CPU从闲置被唤醒的阶段(CPU Wake Overhead)

      5.png

    • 使用Instrument中的Time Profile工具查看该阶段更详细的信息

      (比如使用Location Energy Model确保应用如预期中正确地使用定位功能)

      6.png

    • 使用MetricKit收集用户的性能数据

      7.png

        // 创建遵守`MXMetricManagerSubscriber`的协议的类AppMetrics
      class AppMetrics: MXMetricManagerSubscriber {
      init() {
      		// 初始化时将AppMetrics加入到`MXMetricManager`单例中
      		let shared = MXMetricManager.shared
      		shared.add(self)
      	}
      	deinit {
      		// 销毁时进行移除
      		let shared = MXMetricManager.shared
      		shared.remove(self)
      	}
      	
        // 处理每日的metrics
      	func didReceive(_ payloads: [MXMetricPayload]) {
      	
      	}
      	
        // 处理diagnostics
      	func didReceive(_ payloads: [MXDiagnositcPayload]) {
      	
      	}
      }
      复制代码
  • 使用Xcode Organizer查看线上性能数据

    Xcode Organizer对MetrixKit收集到的数据进行了聚合,忽略了单一用户的详细数据,展现的是整体的趋势;

    而使用MetricKit可以更具针对性的对某一用户在一段时间内的性能表现进行分析。

    8.png

    • 查看用户的电量使用情况

    9.png

    • Regressions

      Regressions是Xcode 13新增的模块,它将各个版本的性能指标中发生劣化的情况单独拎出来展示,让开发者更清晰的看到哪些性能指标亟待优化。

      10.png

    • 查看问题发生时对应的代码

      11.png

  • 超时响应率和滚动卡顿(Hang rate & Scrolling)

    • 超时响应

      长时间无法响应是导致用户强退应用的重要原因

    • 滚动卡顿

      当在下一次屏幕刷新时,新的内容还未ready就会出现卡顿

    Hang rate & Scrollings是表明APP没有及时响应的两个指标,一旦发生会严重影响用户体验,甚至让用户在使用应用时产生挫败感,从而降低用户的使用APP的意愿。

    • 使用Xcode Organizer查看线上的卡顿情况

      • Hang rate

      12.png

      • Scrolling

      13.png

    • 使用Instrument进行分析

      14.png

      • Thread State Trace

        可以查看线程被阻塞的详细情况

      • System Call Trace

        可以查看系统函数调用的时机和时长

    • 使用XCTest进行性能测试

      func testScrollingAnimationPerformance() throws {
      	app.launch()
      	app.staticTexts["Meal Planner"].tap()
      	let foodCollection = app.collectionViews.firstMatch
      	// `measure`函数默认重复5次,可以通过option设置手动停止
      	let measureOptions = XCTMeasureOptions()
      	measureOptions.invocationOptions = [.manuallyStop]
      	// 开始measure
      	measure(metrics: [XCTOSSignpostMetric.scrollDecelerationMetric], 
      	option: measureOptions) {
          // 滑动
      		foodCollection.swipeUP(velocity: .fast)
          // 停止measure
      		stopMeasuring()
          // 重置状态
      		foodCollection.swipeDown(velocity: .fast)
      	}
      }
      复制代码
    • 使用MetricKit收集线上数据

      在iOS 14中,MetricKit会收集用户使用过程中发生的问题,然后每24小时集中上报一次。

      在iOS 15和MacOS 12中,MetricKit会在用户发生问题后,并且立刻进行上报

    • iOS 15中MetricKit新增动画性能检测的API,能够记录动画期间详细的性能数据和卡顿情况

      func startAnimating() {
       // 标记动画开始执行
       mxSignpostAnimaitionIntervalBegin(
       	log: MXMetricManager.makeLogHandle(category: "animation"_telemetry),
       	name: "custom_animation")
       )
      }
      
      func animationDidComplete() {
      	// 标记动画结束
      	mxSignpost(OSSignpostType.end, log: MXMetricManager.makeLogHandle(category: "animation_telemetry"), name: "custom_animation")
      }
      复制代码
      
      > 注:MXSignpost是MetricKit中封装的API,可以用来监控关键代码的运行情况
    
    ![15.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/38fcd4eff5764b208e36dc466137b27c~tplv-k3u1fbpfcp-watermark.image)
    
    
    复制代码
  • 磁盘写入

    • 使用Instrument中的File Activity查看磁盘写入情况

      16.png

      • 优化建议:

        • 对于频繁写入的case,推荐使用Core Data

        • 避免快速创建和删除文件

    • 使用XCTest进行性能测试

      func testSaveMeal() {
      	let app = XCUIApplication()
      	let options = XCTMeasureOptions()
      	options.invocationOptions = [.manullyStart]
      	// 检测下面代码运行时的磁盘写入情况
      	measure(metrics: [XCTStorageMetric(application: app)], options: options) {
      	app.launch()
      	startMeasuring()
      	
      	let firstCell = app.cells.firstMatch
      	firstCell.buttons["Save meal"].firstMatch.tap()
      	
      	let savedButton = firstCell.buttons["Saved"].firshMatch
      	XCTAssertTure(savedButton.waitForExistence(timeout: 2))
      	}
      }
      复制代码
    • 使用Xcode Organizer查看线上磁盘写入情况

      17.png

      • 查看在Disk Writes报告中可以查看24小时内写入量超过1GB的case

      18.png

      • 在Xcode 13中,还可以得到一些优化建议

      19.png

    • 使用MetricKit收集用户的磁盘写入情况

      // 标记开始磁盘写入
      func syncAllContentsToDB() {
      	mxSignpost(OSSignpostType.begin, 
      	log:MXMetricManager.makeLogHandle(categroy: "diskWrite_telemetry"),
      	name: "custom_diskWrites")
      	
      	// sync contents to database
      	
        // 标记磁盘写入结束
      	mxSignpost(OSSignpostType.end,
      	log:MXMetricManager.makeLogHandle(category: "diskWrite_telemetry"),
      	name: "custom_diskWrites")
      }
      复制代码
  • 启动时间

    • 使用Xcode Organizer查看线上启动数据

      20.png

      • 查看因启动超时导致的程序终止

      21.png

    • 使用Instrument中的App Launch工具进一步分析

      22.png

  • Memory

    • 使用Xcode Organizer查看线上内存使用情况

      23.png

    • 使用Instrument中的Leak、Allocations和VM Tracker三个模板

      • Leak检测内存泄漏
      • Allocations分析内存的生命周期
      • VM Tracker展示虚拟内存空间的使用情况
    • 使用MetricKit收集线上数据

      func saveAppAssets() {
      	mxSignpost(OSSignpostType.begin, 
      	log: MXMetricManager.makeLogHandle(category: "memory_telemetry"),
      	name: "custom_memory")
      	
      	// save app metadata
      	
      	mxSignpost(OSSignpostType.end,
      	log: MXMetricManger.makeLogHandle(category: "memory_telemetry"),
      	name: "custom_memory")
      }
      复制代码

更多有关电量优化的Session:

Improving battery life and performance WWDC19

Analyze HTTP traffic in Instruments WWDC 21

更多Hang优化的Session:

Understand and Eliminate Hangs from you app WWDC21

更多滚动优化的Session:

Explore UI animation hitches and the render loop WWDC20

Eliminate animation hitches with XCTest WWDC20

更多磁盘写入优化的Session:

Diagnose power and performance regressions in your app WWDC21

更多启动优化的Session:

Why is my app getting killed WWDC20

更多内存优化的Session:

Detect and diagnose memory issues

更多关于性能工具的Session:

Diagnose performance issues with Xcode Organizer WWDC20

What’s new in MetricKit WWDC20

Identify trends with Power and Performance API WWDC20

Getting started with Instruments WWDC19

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享