📄
Henry
  • Henry的神秘小屋
  • 其他
    • 字节码与机器码的区别?
  • ObjectiveC
    • NSInvocation
    • 检测OC项目中未使用的方法
    • Method Selector
    • 消息转发
  • Swift
    • 检测Swift项目中未使用的类 方法 属性
    • NSCoding
    • Mirror
    • JSONEncode JSONDecode
    • Any AnyObject AnyClass
    • is as? as! as
  • Cocoapods
    • 看懂Podfile.lock文件
    • 在编写的Pod中使用宏预编译
  • iOS
    • 苹果应用 保持画面流畅
    • 关于计算机展示图像的一些问题
    • @testable
    • iOS中URLRequest的缓存策略
    • CodePush接入流程
    • H5在WKWebView中读取沙盒文件
    • FDLog App客户端日志系统
    • 如何实现JSBridge基于WKWebView
    • 网络请求各个指标的度量
    • iOS13 UIModalPresentationStyle
    • 实现H5离线包机制
    • NSURLProtocol 拦截器
    • Framework
    • Lock
    • CFNetwork NSURLSession NSURLConnection
    • setNeedsLayout layoutIfNeeded layoutSubviews
    • StackView
    • Flutter Method Channel:从Dart到Native调用链
    • JSONSerialization.ReadingOptions
    • JSONSerialization.WritingOptions
    • RunLoop高级2
    • RunLoop高级1
    • RunLoop中级
    • RunLoop初级
    • LineBreak AutoShrink
    • 如何给H5出WebView调试包
    • TODO、FIXME、!!!、???、MARK
    • Operation的使用
    • UserDefault
    • 了解WKWebView
    • 输出日志信息到系统控制台
    • Float Double 失去精度问题
    • 使用xcodebuild命令打包导出
    • 在iOS项目中使用C++定义的模块
    • 证书问题
    • 创建常驻线程
  • 源码
    • 阅读PINCache源码
    • 解读AspectHook
    • HandyJSON是如何实现的?
  • 汇编
    • 看懂汇编
由 GitBook 提供支持
在本页

这有帮助吗?

  1. iOS

苹果应用 保持画面流畅

上一页iOS下一页关于计算机展示图像的一些问题

最后更新于5年前

这有帮助吗?

从上面的图中可以看到,CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。所以开发时,也需要分别对 CPU 和 GPU 压力进行评估和优化。

一,CPU的消耗:(也是避免阻塞主线程,比如你写 while(true){} 100% cpu占用,主线程阻死)

  1. 对象的创建: 比如 基于CALayer这一类视图控件,注意的是UI控件系统是不允许在背后线程创建的,只能在主线程创建,但是你可以保持尽量少的创建对象来减少对CPU消耗,通过storyboard创建视图会比通过代码创建消耗的资源多,但是各有各的好处。如果一些比较消耗性能的视图尽量避免。

  2. 对象的调整: 减少不必要的层级关系调整,布局更改。

  3. 布局计算:尽量在一次布局中设置相应的改变,而不是多次频繁的改动布局。

  4. Autolayout:在视图超级多的时候会耗时会明显增多,至少200视图起,200视图以内并不明显。

  5. 文本计算:尽量避免 文本的宽高复杂计算

  6. 文本渲染:屏幕上能看到的所有文本内容控件,包括 UIWebView,在底层都是通过 CoreText 排版、绘制为 Bitmap 显示的。常见的文本控件 (UILabel、UITextView 等),其排版和绘制都是在主线程进行的,当显示大量文本时,CPU 的压力会非常大。对此解决方案只有一个,那就是自定义文本控件,用 TextKit 或最底层的 CoreText 对文本异步绘制。尽管这实现起来非常麻烦,但其带来的优势也非常大,CoreText 对象创建好后,能直接获取文本的宽高等信息,避免了多次计算(调整 UILabel 大小时算一遍、UILabel 绘制时内部再算一遍);CoreText 对象占用内存较少,可以缓存下来以备稍后多次渲染。

  7. 图片解码:后台解码bitmap直接生成图片,然后主线程使用。

  8. 图像绘制:drawRect方法,由于CoreGraphic是线程安全的,可以在背后线程操作,然后在主线程里面将image赋值给layer.content

二,GPU的消耗:

  1. 纹理渲染:所有从内存提交显存的内容,这里涉及到提交到显存的过程和渲染纹理的过程都是在消耗GPU,避免在短时间大量显示图片等内容,如果可以多个图片合成,就显示合成图片。

  2. 视图的混合:当视图层级比较复杂,GPU会混合这些视图层级,越复杂的层级,GPU混合就越消耗GPU资源,尽量减少图片和视图层级,也可以提前合成一张图片。

  3. 图形的生成:CALayer 的 border,圆角,mask,阴影这些通常会触发离屏渲染,而离屏渲染通常发生在GPU中,当一个tableview出现大量的这种视图,由于GPU需要更长的时间去渲染。导致每秒给到显示卡的图像变少了,也就是FPS变低了,如果FPS太低就会肉眼感觉到明显的卡顿了。 可以使用 CALayer.shouldRasterize 光栅化来转嫁到CPU上来处理,或者用一张带自带圆角的图片进行合成。