UIKit 如何捕获渲染第一帧所需的时间

问题描述 投票:0回答:1

我正在为我们的应用程序实现遥测,我试图捕获的事情之一是 Apple 工程师在 WWDC 2019 的“优化应用程序启动”视频中描述的不同时间段。我很难准确捕捉第一帧和扩展阶段的时间。 我试图捕获它们,如下面的代码片段所示,并使用路标来表示记录点(每个

log..Started

log...Finished
。我所做的假设是:

在渲染第一帧之前调用
    application:didFinishLaunchingWithOptions:
  1. 方法(如视频中所述)
    当前运行循环结束后,第一帧将完成渲染。
  2. void PerformWhenIdle(dispatch_block_t block) { CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAfterWaiting, NO, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { block(); }); } // ---------------------------- // AppDelegate.m - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [logger logFirstFrameRenderingStarted]; PerformWhenIdle(^{ [logger logFirstFrameRenderingFinished]; [logger logExtendedStageStarted]; }); } // ---------------------------- // in TableVC.m - (void)viewDidAppear { [self.tableView reloadData]; PerformWhenIdle(^{ [logger logExtendedStageFinished]; }); }
当我检查仪器中的路标时,似乎第一帧的起点非常接近,但是第一帧似乎相当偏离,因此相比之下,扩展阶段似乎非常短,其中路标指示应用程序的持续时间为 225.23ms生命周期仪器显示花费了 1.78 毫秒:

enter image description here 我想知道

我的假设不正确吗?如果是,是否说明仪器有问题?
  1. 如果它们不正确,我怎样才能最好地捕获正在渲染的第一帧的起点和终点?
ios uikit grand-central-dispatch lifecycle cfrunloop
1个回答
0
投票

application:didFinishLaunchingWithOptions: 方法确实在第一帧渲染之前被调用,但这并不是帧渲染开始时的最终决定。

当系统完成第一个绘制周期时,第一帧被视为已渲染。第一帧的持续时间应涵盖整个绘图周期,而不仅仅是立即回调。

void PerformWhenIdle(dispatch_block_t block) { CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, // Changed to kCFRunLoopBeforeWaiting NO, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { block(); CFRunLoopRemoveObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode); CFRelease(observer); }); CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode); } // ---------------------------- // AppDelegate.m - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [logger logFirstFrameRenderingStarted]; PerformWhenIdle(^{ [logger logFirstFrameRenderingFinished]; [logger logExtendedStageStarted]; }); return YES; // Ensure you return YES from didFinishLaunchingWithOptions } // ---------------------------- // in TableVC.m - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.tableView reloadData]; PerformWhenIdle(^{ [logger logExtendedStageFinished]; }); }

请尝试一下,如果有帮助请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.