iOS开发进阶:性能优化与稳定性优化实践
优化实践主要包括UI界⾯的优化、稳定性的优化两部分,是在开发过程中对于相关问题的认知和解决⽅案,仅代表个⼈观点,如有疑问,欢迎⼀起探讨学习。
⼀、UI界⾯优化
在渲染流程中GPU、CPU、显⽰器协同⼯作。CPU计算好显⽰的内容(包括视图的创建、布局计算、图⽚解码、⽂本绘制等),再提交打给GPU进⾏变换、图层合成、纹理渲染,并将渲染的结果提交到帧缓冲区,等带下⼀次VSync信号显⽰到屏幕上。
xcode界面针对这个问题,可以分别对CPU、GPU做⼀些⽅⾯的优化:
针对CPU的优化:在⼦线程进⾏对象的创建、调整、销毁;在⼦线程中预排版、预渲染;异步绘制等等
针对GPU的优化:避免离屏渲染,减少涂层的复杂度等。
1.界⾯布局优化之预排版
在UITableView和UICollectionView中单元格的现实需要提供给代理⽅法对应的⾼度),以快速决定后续
单元格布局的位置,⽽单元格⾼度与实际渲染的数据相关。我们可以在heightForRow(...)和cellForRow(...)⽅法中通过临时布局计算单元格的⾼度和实际数据的渲染,但是这样⼀来就进⾏了多次布局计算,如果界⾯⾮常复杂,这⾥势必会出现卡顿。
解决⽅案:⽹络数据返回后进⾏布局运算,⽣成数据模型。⽐如复杂业务逻辑的判断、图像显⽰的frame、⽂本显⽰的frame、单元格height、富⽂本拼接、折叠展开数据的计算。计算完毕之后再切换到主线程刷新⽤户界⾯。1.heightForRow(...)中通过遍历到模型,返回模型上计算好的⾼度。2.cellForRow(...)⽅法中使⽤计算好的模型进⾏⽤户界⾯的布局显⽰。
优缺点:⼀次布局计算完成后后续可以直接取出来进⾏渲染,避免多次布局计算,体改滑动渲染的效率。如果数据量特别⼤,可以在预估数据能覆盖整个屏幕的情况下切换到主线程进⾏界⾯的渲染,计算完成后再刷新⼀下⽤户界⾯。
2、界⾯渲染优化之预解码/预渲染
图像的现实需要⽹络获取到图⽚的Data-Buffer,再解码⽣成Image-Buffer,⽽整个解码的过程是⽐较耗费性能的。如果有⼤量的⽹络图⽚需要加载,这⾥可能就会造成⼀定程度的卡顿。
解决⽅案:⽹络图⽚在⼦线程中提前解码,然后将解码后的数据绑定在模型上。显⽰的时候直接设置模型中的数据。
关于这⼀点在创建的图⽚加载⽹络框架中都是有迹可循的,⽐如在SDWebImage框架中SDWebImageDownloaderOperation中:
绘制流程
假如视图⾮常复杂(⼦视图较多、布局相互依赖、有⼤量图⽚需要解码),那么这个CPU+GPU的⼯作就可能超过1帧的时间,这样在快速滑动的过程中就会造成卡顿,接⼝给我们提供了优化的空间,也就是在[UIView displayLayer:]中,⾃⼰进⾏计算布局和绘制,整个过程中我们可以放在⼦线程中进⾏,不影响主线程处理滑动等其他的UI事务,这样就不会卡顿。需要补充⼀点,如果有⼤量的计算在整个滑动的过程中有时候会出现局部的空⽩,这是正常的,毕竟计算布局是在⼦线程中异步操作的,如果没有计算完毕则渲染出来的就会没有内容。
详细的绘制流程和原理可以参考YYKit开源框架的YYAsyncLayer和YYLabel的实现流程。
4、界⾯渲染优化之离屏渲染
离屏渲染的检测⽅式:选中模拟器 ->Debug -> Off Off-screen Rendered,如果使⽤离屏渲染会有黄⾊的背景,⽐如系统的电池。
GPU的渲染分为当前屏幕渲染(On-Screen Rendering)和离屏渲染(Off-Screen Rendering)。当前屏幕渲染的原理上⾯已经介绍了,在⼀次Vsync信号周期内CPU计算好布局等,然后将计好的内容交给GPU渲染。GPU渲染好之后就会放⼊帧缓冲区。所谓离屏渲染就是指GPU在当前屏幕的帧缓冲区意外开辟⼀个新的缓冲区进⾏渲染操作。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论