最近在跑性能测试对比各个页面的FPS数据,发现在ios高刷机上flutter页面FPS数据更高 具体看滑动曲线,发现Flutter页面的大部分场景都是120,少数卡顿场景低于120。

但是原生页面FPS会在60~120之间动态浮动,少数情况能上升到120

通过CADisplayLink回调也可以看到实时帧耗时,原生页面大部分场景在16.6ms左右,flutter页面滚动场景维持在8.3ms左右 要了解这背后的原理就要先了解iOS上的动态刷新率支持ProMotion。ProMotion 是 iOS 在支持高刷之后出现的动态刷新率支持,也就是不同场景使用不同的屏幕刷新率,目的是实现体验上提升的同时降低了电池的消耗。
所以即使在设置高刷打开的情况下,出于体验和能耗的综合考虑,原生页面也不会默认维持120HZ的帧率,而Flutter Engine在启动时会限制刷新频率为屏幕最大刷新频率,所以大部分大部分场景可以维持在120HZ左右
vsync_waiter_ios.cc
- (instancetype)initWithTaskRunner:(fml::RefPtr<fml::TaskRunner>)task_runner
callback:(flutter::VsyncWaiter::Callback)callback {
self = [super init];
if (self) {
current_refresh_rate_ = [DisplayLinkManager displayRefreshRate];
_allowPauseAfterVsync = YES;
callback_ = std::move(callback);
display_link_ = fml::scoped_nsobject<CADisplayLink> {
[[CADisplayLink displayLinkWithTarget:self selector:@selector(onDisplayLink:)] retain]
};
display_link_.get().paused = YES;
[self setMaxRefreshRateIfEnabled];
}
return self;
}
- (void)setMaxRefreshRateIfEnabled {
NSNumber* minimumFrameRateDisabled =
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"];
if (![minimumFrameRateDisabled boolValue]) {
return;
}
double maxFrameRate = fmax([DisplayLinkManager displayRefreshRate], 60);
double minFrameRate = fmax(maxFrameRate / 2, 60);
if (@available(iOS 15.0, *)) {
display_link_.get().preferredFrameRateRange =
CAFrameRateRangeMake(minFrameRate, maxFrameRate, maxFrameRate);
} else if (@available(iOS 10.0, *)) {
display_link_.get().preferredFramesPerSecond = maxFrameRate;
}
}