60 fps ios_ios fps - CSDN
  • iOS性能优化:Instrument 调试界面卡顿

    万次阅读 2017-03-27 20:15:35
    前言 工欲善其事,必先利其器。Instrument对于iOS开发来说,是发现并且解决问题的一把利器。 本文会用到的两个工具包括: ...iOS设备通常是60fps(每秒60帧),也就是说两帧相隔的时间是1/60秒,

    前言

    工欲善其事,必先利其器。Instrument对于iOS开发来说,是发现并且解决问题的一把利器。

    本文会用到的两个工具包括:

    • Time Profiler(获取代码运行时间,一般用来看CPU占用)
    • Core Animation(获取图形绘制情况,FPS,离屏渲染等)

    界面显示的原理

    iOS设备通常是60fps(每秒60帧),也就是说两帧相隔的时间是1/60秒,大概16.7ms。在这16.7ms中,为了显示一帧,需要如下工作

    • CPU计算好各个视图的位置,大小,对图片进行解码等,绘制成纹理交给GPU
    • GPU对收到的纹理进行混合,顶点变换,渲染到帧缓冲区
    • 每16.7ms,一个时钟信号到达,帧缓冲区取出一帧,显示到屏幕。

    也就是说,CPU或者GPU被大量占用的时候,都有可能在16.7ms中没办法完成一帧的绘制,导致时钟信号到来的时候,取得还是上一帧的内容,也就都有可能导致界面卡顿


    离屏渲染

    在iOS中,渲染通常分为CPU和GPU渲染两种,而GPU渲染又分为在GPU缓冲区和非GPU缓冲区两种

    • CPU渲染(软件渲染),CPU绘制成bitmap,交给GPU
    • GPU渲染(硬件渲染) 
      • GPU缓冲区渲染
      • 非GPU缓冲区渲染(额外开辟缓冲区)

    通常,CPU渲染,和GPU非帧缓冲区内渲染统称为离屏渲染。因为,CPU和帧缓冲区是为图形图像显示做了高度优化的,速度较快。

    什么情况下会触发离屏幕渲染?

    • 用CoreGraphics的CGContext绘制的
    • drawRect中绘制的,即使drawRect是空的
    • Layer具有Mask(比如圆角)或者Shadow
    • Layer的隔栅化shouldRasterize为True
    • 文本(UILabel,UITextfield,UITextView,CoreText,UITextLayer等)

    离屏渲染一定会引起性能问题吗?

    很少会,比如drawRect这个方法,只会在时图进行重新绘制的时候才会调用。也就是说,假如你的View并不会频繁重绘,那么即使实现了drawRect,也没什么关系。

    对了,目前iOS设备的硬件越来越好也是一个原因,想要要性能差也挺难的。

    CoreGraphics VS CALayer

    上文提到了,CoreGraphics通常是CPU渲染成bitmap交给GPU,假如频繁的大量的绘制出现,往往会导致界面卡顿。而CALayer是对GPU做过优化的,能够硬件加速。所以,对于性能要求较高的绘制,尝试用CALayer替代CoreGraphics


    一个反面教材

    一定要在真机上测试性能才有意义,本文是采用iPhone 5s来调试的。一般测试性能支持的性能最差的就可以了,如果是iOS 8要测试4s上的性能。

    界面很简单,一个ImageView,右侧是随机生成的100个字符,富文本显示。


    Time Profile

    1.打开Time Profile,然后运行想要分析的App

    2.进入主界面,上下滚动List,让Time Profile采集数据, 
    勾选右侧的

    • Separate by Thread,按线程区分
    • Invert Call Tree ,逆向Call Tree,方便我们查看方法调用顺序
    • Hide System Libraries,隐藏系统的库,因为通常系统的代码并不会影响性能

    3.可以选择一段时间,来分析这段时间CPU的使用情况 

    4.找到占用时间最多的代码

    然后,双击占用最多的这一行,进入实际的代码,看看到底哪里占用比较多

    这里,我们看到是这一行代码cell.testLabel?.attributedText = mutableAttr。 
    占用最多的CPU时间。

    我们先来看下整个方法代码,

    • TableViewCell其实很简单,就一个ImageView(带圆角,阴影),一个UILabel
    • cellForRowAtIndexPath里会随机的生成100个字符,然后用AttributeText来让UILabel显示

    乍一看,问题应该是这个随机生成100个字符的函数啊

        func calculateRandomText()->String{
            var result = ""
            for _ in 0...100{
                let random = getRandomCharFromString(globalStr)
                result.appendContentsOf(random)
            }
            return result
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    因为,每一次CellForRow调用的时候,都会计算100次。然后,我们实际分析的时候,发现其实100次对显示来说,真不算什么,也不是卡顿的原因。

    那么,为什么设置attributeText占用时间这么多呢?

    其实很简单,attributeText是建立在TextKit上的,由于每一次显示都是随机的attributeText,每一次都要重新计算文本的大小,位置等等。另外,UIKit中,提供的文本渲染都是在CPU中进行的,渲染成Bitmap,然后交给GPU,所以导致设置attributeText的时候,占用很多时间。

    这里不得不提到:一定不要过早优化,优化的时候尽量依赖于Instrument的分析结果,而不是自己的主观感受。尤其当你还是个新司机的时候。


    Core Animation

    在Instrument中,Command+L打开Library,然后添加Core Animation。我们来看看GPU的相关的问题

    最直观的就是滚动视图,查看FPS(Frame per second),一般小于50帧就会看到明显的掉帧。

    备注:这里的很多参考自这本书

    1.看看图层混合情况

    • 只开启Color Blended Layers,然后没有混合的部分会是绿色,混合最严重的部分会是红色。大量的图层混合会消耗GPU的时间,因为对于一个像素点,GPU不能简单的使用最上层的视图的颜色,而是需要进行计算叠加。

    会看到截图如下 

    这里的Cell整个背景都是红的,因为背景是alpha为0.3的View,UILabel是深红色的,因为大量的阴影。

    2.看看隔栅化情况,

    • 只开启Color Hits Green and Misses Red,当使用shouldRasterize属性的时候,耗时的图层绘制会被缓存,然后当做一个简单的扁平图片呈现。当缓存无法使用必须重建的时候,会被高亮为红色。

    截图如下:

    3.看看拷贝图片情况

    • 只开启Color Copied Images - 有时候寄宿图片的生成意味着Core Animation被强制生成一些图片,然后发送到渲染服务器,而不是简单的指向原始指针。这个选项把这些图片渲染成蓝色。复制图片对内存和CPU使用来说都是一项非常昂贵的操作,所以应该尽可能的避免。

    我的测试项目里没有这个,所以不贴图了。

    4.看看图片有没有像素不对齐,有没有拉伸和缩放

    • Color Misaligned Images,可以看到如下。(因为我们的缩略图其实是一张很大的图,所以被缩放了,导致显示成黄色)

    5.看看离屏渲染

    -只开启Color Offscreen-Rendered Yellow,离屏幕渲染的部分会被高亮成黄色

    6.其他选项

    • Color Immediately 通常Core Animation Instruments以每毫秒10次的频率更新图层调试颜色。对某些效果来说,这显然太慢了。这个选项就可以用来设置每帧都更新
    • Color OpenGL Fast Path Blue 这个选项会对任何直接使用OpenGL绘制的图层进行高亮
    • Flash Updated Region 这个选项会对重绘的内容高亮成黄色(也就是任何在软件层面使用Core Graphics绘制的图层)。这种绘图的速度很慢。

    界面顿卡的原因

    界面顿卡主要从两个角度考虑

    CPU限制

    • 对象的创建,释放,属性调整。这里尤其要提一下属性调整,CALayer的属性调整的时候是会创建隐式动画的,是比较损耗性能的。
    • 视图和文本的布局计算,AutoLayout的布局计算都是在主线程上的,所以占用CPU时间也很多 。U
    • 文本渲染,诸如UILabel和UITextview都是在主线程渲染的
    • 图片的解码,这里要提到的是,通常UIImage只有在交给GPU之前的一瞬间,CPU才会对其解码。

    GPU限制

    • 视图的混合。比如一个界面十几层的视图叠加到一起,GPU不得不计算每个像素点药显示的像素
    • 离屏渲染。视图的Mask,圆角,阴影。
    • 半透明,GPU不得不进行数学计算,如果是不透明的,CPU只需要取上层的就可以了
    • 浮点数像素

    界面顿卡的优化

    建议使用成熟的”轮子”,因为作为一个开发者,你的工作是写出高质量的App,那么为什么不用那些已经验证成功的框架呢?如果真的轮子不能实现,或者你有闲下来的时间,再造轮子未尝不可。

    使用AsyncDisplayKit

    使用FaceBook出品的AsyncDisplayKit来写复杂的界面。能够获得异步绘制,预先加载等诸多好处。不过,需要一定的学习成本,前段时间看了下网易新闻的安装包,就使用了AsyncDisplayKit

    图文混排引擎

    大多数性能要求较高的界面就是图文混排,比如微博Feed,微信朋友圈等界面。建议使用成熟的图文混排引擎,因为这些引擎一般支持异步绘制,并且做了大量优化。推荐两个


    异步绘制

    把复杂的界面,放到后台线程里绘制成一个bitmap,然后再显示。虽然有些延迟,不过换来的却是平滑的界面。

    图片的解码

    建议使用成熟的库,比如SDWebImage等,能够在后台进行图片解码,减少CPU的使用。

    预加载与缓存

    对于复杂的TableView,可以对Cell视图的各个控件的大小,位置后台进行预计算,并且缓存起来。这样保证在heightForRowcellForRow中不进行大量的计算。

    尽量使用CALayer

    因为Layer是一个轻量级的视图结构,它不接受通知,不接受触摸,不在响应链。所以,相对于UIView来说,它的性能较好。并且CALayer及其子类是可以使用GPU渲染的,能够硬件加速。

    图层预合成

    将两个CALayer的内容合成到一个Bitmap里,然后显示。能够减轻GPU的压力


    资料

    建议看看这几篇文章

    展开全文
  • iOSAPP开发FPS的测试技巧

    千次阅读 2018-01-20 13:20:16
    我们知道iOS设备的刷新率基本都是60FPS(PS:去年出的ipad pro刷新率是120).所以iOS的APP用起来一般都不会感觉到卡顿的情况.除非你UI的某些地方写的有问题导致严重掉帧.但是,我们如何来看FPS的数值呢. 在安卓里面我们...
        我们知道iOS设备的刷新率基本都是60FPS(PS:去年出的ipad pro刷新率是120).所以iOS的APP用起来一般都不会感觉到卡顿的情况.除非你UI的某些地方写的有问题导致严重掉帧.但是,我们如何来看FPS的数值呢.
        在安卓里面我们可以去系统的设置那里去调.可以看渲染效率什么的.但是在iOS中却没有这种功能.
        我们可能都用过一个叫YYKit的库(富文本的YYText.json模型互相转换的YYmodel).在富文本那一块儿,运行单独的YYText示例程序.我们在其中的一个带async的示例中看到了一个FPS的指示器
    

    YYText示例程序

        虽说YYKit中有很多YY系列的组件.但就是找不到关于这个Label的组件.github搜索YY+FPS这两个关键词就会找到一个名叫YYFPSLabel的组件.这个就是那个显示FPS的组件了.使用起来也非常的容易.
    

    YYFPSLabel示例程序

        因为我个人比较懒.所以需求就是在每个页面都显示FPSLabel.最好不会消除的那种.而且需要FPSLabel出现在Window的最上层.
    
        //因为我集成了masonry所以下面就直接使用masonry来设置了
        YYFPSLabel *fpsLabel = [[YYFPSLabel alloc] init];
        [self.window addSubview:fpsLabel];
        [fpsLabel bringSubviewToFront:self.window];//这句代码会把fpsLabel放到self.window的最顶层.
        [fpsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.equalTo(self.window);
            make.centerY.equalTo(self.window);
        }];
    展开全文
  • 在项目开发中,有的时候需要查看实时的FPS值,以此作为性能的参考。 优势 实时显示FPS值。 可以拖到任意位置贴边,不影响调试。 效果图 使用 将OttoFPSButton目录拖到目标工程下,在AppDelegate.m里面加入下面...
        

    OttoFPSButton

    前言

    在项目开发中,有的时候需要查看实时的FPS值,以此作为性能的参考。

    优势

    1. 实时显示FPS值。
    2. 可以拖到任意位置贴边,不影响调试。

    效果图

    使用效果

    可随意拖动位置,不影响调试

    使用

    将OttoFPSButton目录拖到目标工程下,在AppDelegate.m里面加入下面代码

    #import "OttoFPSButton.h"
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self.window makeKeyAndVisible];
    
    CGRect frame = CGRectMake(0, 300, 80, 30);
    UIColor *btnBGColor = [UIColor colorWithWhite:0.000 alpha:0.700];
    OttoFPSButton *btn = [OttoFPSButton setTouchWithFrame:frame titleColor:[UIColor whiteColor] titleFont:[UIFont systemFontOfSize:15] backgroundColor:btnBGColor backgroundImage:nil];
    [self.window addSubview:btn];
    
    return YES;
    }

    这样就能在项目中看到FPS的状态变化了。

    点我下载Demo

    展开全文
  • FPS的计算 CoreAnimation有一个很好用的类CADisplayLink,这个类会在每一帧绘制之前调用,并且可以获取时间戳。于是,我们只要统计出,在1s内的帧数即可。 import UIKit class FPSMonitor: UILabel { private var...

    原理

    FPS的计算

    CoreAnimation有一个很好用的类CADisplayLink,这个类会在每一帧绘制之前调用,并且可以获取时间戳。于是,我们只要统计出,在1s内的帧数即可。

    import UIKit
    
    class FPSMonitor: UILabel {
    
        private var link: CADisplayLink = CADisplayLink.init()
        private var count: NSInteger = 0
        private var lastTime: TimeInterval = 0.0
        private var fpsColor: UIColor = UIColor.green
        public var fps: Double = 0.0
        
        // MARK: - init
        
        override init(frame: CGRect) {
            var f = frame
            if f.size == CGSize.zero {
                f.size = CGSize(width: 55.0, height: 22.0)
            }
            super.init(frame: f)
            
            self.textColor = UIColor.white
            self.textAlignment = .center
            self.font = UIFont.init(name: "Menlo", size: 12.0)
            self.backgroundColor = UIColor.black
            
            link = CADisplayLink.init(target: LSLWeakProxy(target: self), selector: #selector(tick))
            link.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)
        }
        
        deinit {
            link.invalidate()
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        // MARK: - actions
        
        @objc func tick(link: CADisplayLink) {
            guard lastTime != 0 else {
                lastTime = link.timestamp
                return
            }
            
            count += 1
            let delta = link.timestamp - lastTime
            guard delta >= 1.0 else {
                return
            }
            
            lastTime = link.timestamp
            fps = Double(count) / delta
            let fpsText = "\(String.init(format: "%.3f", fps)) FPS"
            count = 0
            
            let attrMStr = NSMutableAttributedString(attributedString: NSAttributedString(string: fpsText))
            if fps > 55.0{
                fpsColor = UIColor.green
            } else if(fps >= 50.0 && fps <= 55.0) {
                fpsColor = UIColor.yellow
            } else {
                fpsColor = UIColor.red
            }
            attrMStr.setAttributes([NSAttributedStringKey.foregroundColor:fpsColor], range: NSMakeRange(0, attrMStr.length - 3))
            attrMStr.setAttributes([NSAttributedStringKey.foregroundColor:UIColor.white], range: NSMakeRange(attrMStr.length - 3, 3))
            DispatchQueue.main.async {
                self.attributedText = attrMStr
            }
        }
    }
    
    展开全文
  • FPS是测量用于保存、显示动态视频的信息数量。通俗来讲就是指动画或视频的画面数。例如在电影视频及数字视频上,每一帧都是静止的图象;快速连续地显示帧便形成了运动的假象。每秒钟帧数 (FPS) 愈多,所显示的动作就...
  • iOS一行代码监测FPS/内存/CPU

    千次阅读 2018-07-26 09:47:43
    网上有不少工具,自己就参考做了一个比较简单的工具WHDebugTool,可以监测内存,CPU和FPS。 GitHub地址:https://github.com/remember17/WHDebugTool   WHDebugTool   1、快速使用方法 1.1 导入头文件 ...
  • JPFPSStatus README ...Show FPS Status on StatusBar Podfile platform :ios, '7.0' pod 'JPFPSStatus', '~> 0.0.2' Instruction Note:Use JPFPSStatus in DEBUG mode add the code in AppDel
  • iOS测试fps方式

    千次阅读 2016-02-18 17:19:22
    Measure Graphics Performance ...Extensive use of graphics in your iOS app can make your app stand out from your competitors. But unless you use graphics resources responsibly, your app will slow
  • ios-FPS实时测试.zip

    2020-07-30 23:33:32
    适合游戏开发的同学放到屏幕上一直测试,技术上不难,但是不熟悉CADisplayLink的同学可能很难想到做法。给个参考。
  • canvasBlurRect, 实时( 30 + FPS ) iOS样式框模糊+ 饱和度带有 HTML5 Canvas canvasBlurRect实时( 30 + FPS ) ios样式框模糊+ 饱和度带有 HTML5 Canvas演示在这里可用 !canvasBlurRect扩展 CanvasRenderingContext...
  • 每一个追求交互自然的产品都希望拥有一套顺畅的使用流程。但开发者可能会忽略一些细节,导致出现性能糟糕的 Web 动画,不仅会产生「页面垃圾」(janky),最直接的就是出现页面卡顿。开发者往往会花大量精力在优化首...
  • iOS开发 - 在状态栏显示FPS,CPU和内存信息

    千次阅读 热门讨论 2016-12-26 23:32:31
    到Github上找了找,发现几乎都是只显示FPS的,而且效果也不是我想要的。于是就自己写了个 源码地址 LHPerformanceStatusBar 效果字体颜色会根据阈值进行颜色变化,性能差的时候字体会变成红色,性能一般的时候会变成...
  • iOS小Tip之查看FPS

    2019-06-30 01:00:31
    可能大家有的时候会想要查看app在运行时的帧率能否达到60帧,如果达不到的话,你可能会想着去优化动画或者其它任何会影响显示性能的问题。 但是,你首先要观察到你的FPS,对吧? 我告诉大家一个简单的方法,不需要...
  • iOS计算FPS

    2019-06-17 19:07:36
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 此资源为CISCO Catalyst 2960X整个系列通用功能齐全的IOS,可以在模拟器中使用。
  • 显示状态栏上方的FPS,CPU使用率,应用程序和iOS版本,并通过delegate报告FPS和CPU使用情况。.zip,Shows FPS, CPU and memory usage, device model, app and iOS versions above the status bar and report FPS, CPU...
  • 如果你对iOS开发足够熟悉的话,那么对Masonry框架应该不陌生。简单的说,Masonry的诞生让AutoLayout的使用更为优雅,让控件的布局更为方便。使用辩证的观点来看一个事物的话,凡事都有两面性,Masonry的使用也不例外...
  • App 的性能问题虽然不会导致 App不可用,但依然会影响到用户体验。如果这个性能问题不断累积,达到临界点以后,问题就会爆发出来。这时,影响到的就不仅仅是用户了,还有负责App开发的你。 线下性能监控 ...
  • iOS逆向之二-一个简单的Tweak插件 Tweak插件可以动态的注入到宿主程序中,修改宿主程序的运行流程 Tweak插件是使用theos开发的,所以首先要安装theos程序,并且越狱手机中需要安装Cydia Substrate,这篇博客iOS逆向...
  • 实现60fps的网易云音乐首页

    千次阅读 2017-07-28 14:38:34
    前言网易云音乐是一款很优秀的音乐软件,我也是它的忠实用户。最近在研究如何更好的开发TableView,接着我写了一个Model驱动的小框架 - MDTable。为了去验证框架的可用性,我选择了网易云音乐的首页来作为Demo,语言...
1 2 3 4 5 ... 20
收藏数 7,958
精华内容 3,183
关键字:

60 fps ios