美文网首页
iOS 浅谈APP性能优化

iOS 浅谈APP性能优化

作者: zbzbwxe | 来源:发表于2020-03-03 19:41 被阅读0次

    做一款APP,它的的性能稳定性问题使我们有限要考虑的,首先我们从几个大方向去谈谈这个问题.

    1.APP 的启动

    启动分为冷启动与热启动:
    1.1 冷启动(Cold Launch)就是APP 从零开始.
    1.2 热启动(Warm Launch)APP已经在内存中,在后台存活,点击图标再次启动.

    我们主要研究冷启动, 冷启动的四大阶段:

    1.dyld 加载可执行文件,动态库(递归加载).

    1.1 dynamic link editor(动态链接编辑器).
    1.2 dynamic loader(动态加载器).

    2.runtime.

    2.1调用map_images进行可执行文件内容的解析和处理.
    2.2在load_images 中调用call_load_method,调用Class和Category的+load方法,进行各种objc结构初始化.
    2.3 调用C++ 静态初始化器.

    到此为止,可执行文件和动态库中所有的符号
    (Class,Protocol,Selector,IMP,...)
    都已经按格式成功加载到内存中,被 runtime 所管理

    3.main()函数执行后.

    main() 函数执行后的阶段,指的是从 main() 函数执行开始,
    到 appDelegate 的 didFinishLaunchingWithOptions 方法里首屏渲染相关方法执行完成.

    3.1首屏初始化所需的配置文件的读写操作.
    3.2首屏列表大数据读取.
    3.3首屏渲染大量计算.

    4.首屏渲染完成后.

    总结:

    APP的启动由dyld主导,将可执行文件加载到内存,顺便加载所有依赖的动态库, 并由runtime负责加载成objc定义的结构,所有初始化工作结束后,dyld就会调用main函数, 接下来就是UIApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法.

    2.安装包瘦身.
    3.卡顿问题优化.
    4.耗电量优化.

    优化方案:

    一. 启动阶段优化

    1. dyld 阶段:

    1).减少动态库的加载,合并一些动态库.
    2).减少Objc类、分类的数量,减少Selector(选择器)数量.
    3).Swift 尽量使用Struct、枚举.

    2. runtime阶段:

    用+initialize方法和dispatch_once取代C++ 的静态构造器、Objc的+load.
    (因为在+load()方法里,runtime进行方法替换操作会带来4ms的损耗)

    3. main()函数执行后

    1.main()函数开始执行后到首屏渲染完成前的这一段时间,只处理首屏相关业务,其他的非首屏业务的初始化(监听注册、配置文件读取...)放在首屏渲染完成后再做处理.

    4.首屏渲染

    1.不使用xib, 直接使用代码加载首屏视图.
    2.NSUserDefaults实际上是在Library文件夹下会产生一个plist文件,如果文件太大的话,一次读取到内存中比较耗时,需要拆分.
    3.每次用NSLog方式打印会隐式的创建日历(Calendar),需要删减启动业务的NSLog.
    4.启动时发送的网络请求,都可以统一在异步线程中请求.

    二. 安装包瘦身

    安装包(IPA) == 资源 + 可执行文件
    1.资源(图片、音频、视频)采取无损压缩,除去无用的资源.
    2.编译器优化,去掉异常支持, 利用AppCode, 编写LLVM插件检测重复未被调用代码.

    三. 卡顿问题

    1. 尽可能减少GPU、GPU 的资源消耗.
    2. 尽量用轻量级的对象.(比如在用不到事件点击的情况使用CALayer 代替UIView)
    3. 不要频繁的调用UIView 的相关属性.
    4. 尽量提前计算好布局,尽量减少多次属性的修改.
    5. Autolayout会直接消耗更多的CPU资源.
    6. 控制线程的最大并发数.
    7. 减少视图的层次.
    8. 减少透明视图的设置.
    9. 把耗时操作放在子线程.(文本处理(尺寸计算、绘制)、 (图片处理(解码、绘制)))
    10. 离屏渲染
      概念:
      在OpenGL中,GPU有2种渲染方式:
      On-Screen Rendering:当前屏幕渲染,在当前用于显示的屏幕缓冲区进行渲染操作.
      Off-Screen Rendering:离屏渲染,在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作.

    离屏渲染消耗性能的原因
    需要创建新的缓冲区
    离屏渲染的整个过程,需要多次切换上下文环境,先是从当前屏幕(On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上,又需要将上下文环境从离屏切换到当前屏幕.

    离屏渲染的触发:

    光栅化: layer.shouldRasterize = YES;
    遮罩: layer.mask
    圆角: 设置layer.masksToBounds = YES、layer.cornerRadius > 0(考虑通过CoreGraphics绘制裁剪圆角,或者叫UI提供圆角图片)
    阴影: 设置了layer.shadowPath就不会产生离屏渲染

    11.内存泄漏查找:

    Analyze

    学 名: 静态分析工具- 查 找: 可以通过 Product ->Analyze 菜单项启动- 快捷键: CMD+shift +b.- Analyze主要分析以下四种问题:

    1. 逻辑错误:访问空指针或未初始化的变量.
    2. 内存管理错误:如内存泄漏等.
    3. 声明错误:从未使用过的变量.
    4. Api调用错误:未包含使用的库和框架.

    Instruments

    学 名: 动态分析工具- 查 找: Product ->Profile 菜单项启动- 快捷键: CMD + i.
    简 介:它有很多跟踪模块可以动态分析和跟踪内存, CPU 和文件系统.

    四. 耗电量优化

    1.尽可能降低CPU、GPU的功耗.
    2.少用定时器.
    3.优化 i/O操作.

    3.1尽量不要频繁的写入小数据,最好批量一次性写入.
    3.2 读大量重要的数据时,考虑用dispatch_io, 其提供了基于GCD的异步操作文件I/O的API, 用dispatch_io系统会优化磁盘访问.
    3.3数据量比较大的时候使用数据库(SQLite、FMDB...)

    4.网络优化

    4.1 减少、压缩网络数据.
    4.2 多次的网络请求相同,使用缓存或者数据库.
    4.3 断点续传,否则网络不稳定的时候可能多次传入的内容相同.
    4.4 网络不可用时,不要尝试网络请求.
    4.5 让用户可以取消长时间运行的网络操作,设置合适的超时时间.
    4.6 批量传入,不要一次一次请求,使用异步加载.

    5.定位优化

    5.1 如果只是快速定位用户位置最好使用CLLocationManager的requestLocation方法,定位完成后,会自动让定位硬件断点.
    5.2 如果不是导航应用,尽量不要实时更新位置,定位完毕后就关掉定位服务.
    5.3 需要后台定位时,尽量设置pausesLocationUpdatesAutomatically 为 YES(如果用户不移动时,系统会自动暂定位置更新).
    5.4 尽量不要使用startMonitoringSignificantLocationChange(开始监视重要的位置更改),优先考虑startMonitoringForRegion(开始区域监控)

    相关文章

      网友评论

          本文标题:iOS 浅谈APP性能优化

          本文链接:https://www.haomeiwen.com/subject/wukdkhtx.html