如何做启动优化,如何监控
iOS启动优化是提升应用程序启动速度和响应性能的一系列技术和方法。下面是一些常用的iOS启动优化方法和监控工具:
启动优化方法:
-
减少冷启动时间:冷启动是指应用进程不在系统中,需要系统分配新的进程来启动应用。为了减少冷启动时间,可以考虑以下优化方法:
- 合并动态库并减少使用Embedded Framework。
- 删除无用代码并抽取重复代码。
- 避免在+load方法中执行耗时操作,使用+initialize代替。
- 避免使用attribute((constructor)),可将要实现的内容放在初始化方法中配合dispatch_once使用。
- 减少非基本类型的C++静态全局变量的个数。
-
优化main函数代理阶段:main函数代理阶段是指从main()函数开始执行到didFinishLaunchingWithOptions方法执行结束的耗时。在这个阶段可以考虑以下优化方法:
- 删除不必要的初始化代码。
- 延迟加载不必要的模块和功能。
- 使用异步加载和懒加载来提高启动速度。
监控工具:
- Xcode Instruments:Xcode自带的性能分析工具,可以使用Time Profiler和System Trace等工具来监控应用程序的启动时间和性能。
- DYLD_PRINT_STATISTICS:通过设置环境变量DYLD_PRINT_STATISTICS或DYLD_PRINT_STATISTICS_DETAILS,可以在Xcode中查看应用程序启动过程中各个阶段的耗时统计信息。
以上是一些常用的iOS启动优化方法和监控工具,通过优化启动流程和使用合适的工具,可以提升应用程序的启动速度和响应性能。
Learn more:
如何做卡顿优化,如何监控
iOS卡顿优化方法可以从两个方面入手:CPU优化和GPU优化。下面将介绍一些常用的优化方法,并提供一些监控工具供参考。
CPU优化方法:
-
减少计算量:
-
图片解码优化:
- 使用SDWebImage等库,在后台线程将图片绘制到CGBitmapContext中,然后直接从Bitmap创建图片 [1].
GPU优化方法:
-
减少渲染量:
-
画圆角避免离屏渲染:
- 使用CAShapeLayer与UIBezierPath配合画圆角 [1].
监控工具:
- Instruments:Xcode自带的性能分析工具,可以监控CPU、内存、网络等性能指标,帮助定位卡顿问题 [2].
- FPS监控:通过在App中添加FPS监控代码,可以实时监测帧率,判断是否存在卡顿 [2].
- 卡顿检测工具:如Facebook的Chisel、Tencent的GT等,可以监测主线程卡顿情况,并提供详细的卡顿堆栈信息 [2].
以上是一些常用的iOS卡顿优化方法和监控工具
Learn more:
FPS 用 CADisplayLinker 来计数
使用CADisplayLink来计算FPS的步骤如下:
- 创建CADisplayLink对象,并将其添加到当前的run loop中的NSRunLoopCommonModes中。这样可以确保CADisplayLink在屏幕刷新时被调用。
- 在CADisplayLink的回调方法中,记录每次调用的次数,并计算时间间隔。
- 当时间间隔超过1秒时,计算FPS并进行相应的处理(例如打印、显示在界面上等)。
- 重置计数和时间戳,以便下一次计算。
以下是一个示例代码:
swift
import UIKit
class ViewController: UIViewController {
var displayLink: CADisplayLink?
var frameCount = 0
var timestamp = 0.0
override func viewDidLoad() {
super.viewDidLoad()
setupDisplayLink()
}
func setupDisplayLink() {
displayLink = CADisplayLink(target: self, selector: #selector(update))
displayLink?.add(to: .current, forMode: .common)
}
@objc func update() {
if timestamp == 0 {
timestamp = displayLink?.timestamp ?? 0
return
}
frameCount += 1
let elapsed = displayLink?.timestamp ?? 0 - timestamp
if elapsed >= 1.0 {
let fps = Double(frameCount) / elapsed
print("FPS: \(fps)")
// Reset
frameCount = 0
timestamp = displayLink?.timestamp ?? 0
}
}
}
这段代码创建了一个CADisplayLink对象,并将其添加到当前的run loop中。在每次屏幕刷新时,会调用update
方法。在update
方法中,我们记录每次调用的次数,并计算时间间隔。当时间间隔超过1秒时,我们计算FPS并进行相应的处理。最后,我们重置计数和时间戳,以便下一次计算。
请注意,使用CADisplayLink计算的FPS只是一个指导意义,不能代表真实的FPS。因为CADisplayLink是以屏幕刷新频率为基准的,而在实际应用中,可能存在其他因素(例如CPU和GPU的性能)影响帧率。因此,这个FPS指示器只能作为一个参考,不能完全准确地反映屏幕的帧率。
Learn more:
怎样监听 runloop 的 source0 事件和进入休眠前,然后设定一个阈值,监听卡顿
要监听 RunLoop 的 source0 事件和进入休眠前的方法,可以使用 CFRunLoopObserver 来实现。CFRunLoopObserver 是一个观察者,可以监听 RunLoop 的状态变化,并在特定的时间点执行相应的操作。
以下是具体的步骤:
-
创建一个 CFRunLoopObserver 对象,并指定观察的时间点和观察的事件类型。可以使用 CFRunLoopObserverCreate 函数来创建观察者对象。
-
定义一个回调函数,用于在观察的时间点执行相应的操作。回调函数的参数包括观察者对象、观察的事件类型和上下文信息。
-
将观察者对象添加到 RunLoop 的指定模式下。可以使用 CFRunLoopAddObserver 函数将观察者对象添加到 RunLoop 中。
-
在回调函数中,可以根据观察的事件类型执行相应的操作。例如,在监听进入休眠前的事件时,可以记录当前时间,并与上一次记录的时间进行比较,判断是否发生了卡顿。
-
根据需要,可以设置一个阈值来判断卡顿的时间。如果超过了阈值,可以进行相应的处理,例如打印日志、发送通知或采取其他措施。
以下是一个示例代码,演示如何监听 RunLoop 的 source0 事件和进入休眠前的方法,并设定一个阈值来监听卡顿:
objective-c
// 定义观察者的回调函数
void runLoopObserverCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
if (activity == kCFRunLoopBeforeSources) {
// 在 source0 事件之前执行的操作
NSLog(@"Before sources");
} else if (activity == kCFRunLoopBeforeWaiting) {
// 在进入休眠前执行的操作
NSLog(@"Before waiting");
// 记录当前时间
NSDate *currentDate = [NSDate date];
// 获取上一次记录的时间
NSDate *lastDate = (__bridge NSDate *)(info);
// 计算时间差
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:lastDate];
// 设置阈值,判断是否发生卡顿
NSTimeInterval threshold = 1.0; // 1秒
if (timeInterval > threshold) {
NSLog(@"Cardon detected");
}
// 更新上一次记录的时间
CFDateRef dateRef = (__bridge_retained CFDateRef)(currentDate);
CFRelease((__bridge CFTypeRef)(lastDate));
*(CFDateRef *)(info) = dateRef;
}
}
// 创建观察者对象
CFRunLoopObserverContext context = {0, (__bridge void *)([NSDate date]), NULL, NULL, NULL};
CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &runLoopObserverCallback, &context);
// 将观察者对象添加到 RunLoop 的默认模式下
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
// 运行 RunLoop
CFRunLoopRun();
// 释放观察者对象
CFRelease(observer);
这样,就可以监听 RunLoop 的 source0 事件和进入休眠前的方法,并设定一个阈值来监听卡顿。
Learn more:
- [iOS面试]第7章 RunLoop相关面试问题 | codeTao
- iOS Runloop 总结 | Edgar's Blog
- GitHub - fanren5119/iOS-runloop: 本届详细讲解了ios的runloop
如何做耗电优化,如何监控
iOS耗电优化方法可以通过以下几个步骤来实现:
-
使用Energy impact进行耗电检测:
-
使用Energy Log进行耗电检测:
-
使用sysdiagnose进行耗电检测:
-
优化耗电量:
Learn more:
如何做网络优化,如何监控
iOS网络优化方法可以从减少请求带宽和降低请求延迟两个方面进行优化。同时,监控网络性能也是很重要的,可以帮助我们了解应用的网络状况并及时发现问题。
以下是一些iOS网络优化的方法和监控网络性能的工具:
iOS网络优化方法:
-
减少请求带宽:
- 使用高效的数据交互模式。
- 在可能的情况下使用预先压缩的数据。
- 压缩每一个请求与响应负载[1]。
-
降低请求延迟:
- 最小化DNS查询的数量,可以使用DNS预下载进行更早的DNS解析。
- 最大程度减少应用发起的连接数,请求结束时不要关闭HTTPS连接,使用域分片等方式来减少SSL握手时间。
- 在单个TCP连接上发送HTTP请求,以管道的形式发送HTTP请求,避免多个TCP连接的开销[1]。
iOS网络性能监控工具:
-
Network Link Conditioner:是iOS开发者工具中的一个功能,可以模拟不同网络环境下的网络连接状况,帮助开发者测试应用在不同网络条件下的性能表现。
-
Charles Proxy:是一款常用的网络抓包工具,可以用于监控和分析iOS设备上的网络请求和响应,帮助开发者了解应用的网络状况。
-
Firebase Performance Monitoring:是Google提供的一款移动应用性能监控工具,可以监控应用的网络请求、响应时间等性能指标,并提供实时的性能报告和分析。
-
Alamofire Network Logger:是一款基于Alamofire网络库的日志记录工具,可以记录和显示iOS应用的网络请求和响应的详细信息,方便开发者进行网络性能分析。
以上是一些常用的iOS网络优化方法和监控工具,通过优化网络性能和监控网络状况,可以提升应用的用户体验和性能表现。
Learn more: