拜伦的博客

Coder Byron

这里有关于iOS,机器学习的笔记心得,欢迎交流


iOS底层(8)- 性能优化

目录

减少卡顿

  • 尽量减少视图数量和层次
  • 减少透明的视图
  • 尽量避免出现离屏渲染

离屏渲染

如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的frame buffer,作为像素数据存储区域,而这也是GPU存储渲染结果的地方。
如果有时因为面临一些限制,无法把渲染结果直接写入frame buffer,而是先暂存在另外的内存区域,之后再写入frame buffer,那么这个过程被称之为离屏渲染。

GPU离屏渲染:采用画家算法,把每一层依次输出到画布,如果父layer剪裁成圆角,容器子layer因为父容器有圆角,也要被剪裁,但这时还在渲染队列中,此时需要在新内存中,把容器以及子layer依次画好,剪裁完成,再放到frame buffer中。

消耗性能原因

  • 需要创建新的缓冲区
  • 整个过程需要多次切换上下文环境,从on-screenoff-screen,等渲染结束后,将离屏缓冲区结果显示到屏幕上,再讲上下文从off-screen切换到on-screen

哪些会触发离屏渲染

  • 光栅化 layer.shouldRasterize= YES。 隐式的创建一个位图,各种阴影遮罩效果保存在位图中缓存,如果对应的layer极其sublayers没有发生改变,在下一帧的时候可以直接复用,减少渲染频率。但是否有助于优化性能取决于缓存的位图是否被有效复用。
  • 遮罩 layer.mask
  • 圆角 同时设置layer.maskToBounds = YES, layer.cornerRadius >0

  • 阴影 layer.shadowoffset..., 但是 layer.shadowPath不会产生离屏渲染

卡顿检测

通过使用监听 runloop的状态切换的耗时达到监控卡顿的目的

APP启动优化

启动分为3大阶段

  • dyld(dynamic link editor) 动态链接,装在Mach-O文件
    • 装在APP可执行文件,递归加载所有依赖的动态库
    • 都完毕后,通知runtime进行下一步处理
  • runtime
    • 调用map_images 进行执行文件内容的解析和处理
    • load_images中调用call_load_methods, 调用所有class和category+load方法
    • 进行objc结构初始化,注册类,初始化对象等
    • 可执行文件和动态库中所有符号Class,Protocol, Selctor, IMP 都已经加载完成
    • 调用Main函数
  • main
    • UIApplicationMaindidFinishLaunchingWithOptions方法

优化方案:

  • dyld
    • 减少动态库,合并动态库
    • 减少Objc类,分类的数量
  • runtime
    • +initialize方法和dispath_once代替+load方法
  • main
    • 按需加载

更多详细优化方案见iOS 应用启动耗时分析及优化

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦