新疆都市网_打造全面的专业的企业资讯门户!
您当前的位置 : 新疆都市网  >  美食
移动端启动速度
2020-03-29 10:32:37 来源:互联网 阅读:-

一款App,启动速度是最最大的门面,也是用户接触app的第一印象,试想,第一次进入app,就打不开,或者过了N秒才能进入主界面,会有多少用户有耐心继续使用下去。

所以这篇文章会从Android和iOS两个维度,根据启动机制的差异介绍一下启动速度的优化方式。



Android


启动分析

对于Android的启动分析,有一张很经典的图:

image.png

  • T0到T1:用户点击了图标,这时候首先响应操作的并不是app,而是rom的Launcher,然后就是大家熟知的AMS和WMS操作,这块讲起来有些复杂,之后会放到一个单独的文章中,而且这里的优化其实是app根本插不上手的,所以不是本文重点。在系统拉起进程之前,需要先显示一个预览窗口,这个是在app中配置的theme,如果theme是透明的,现在还是看到的桌面。这里不建议进行透明配置,会给用户一个点击延迟的错觉。iOS在这里处理的很好,虽然机制不同,但是在点击图标后,会先去显示Launcher画面,这个是一个固定配置,所以交互感觉更友好一些。
  • T1到T2:进程创建完毕了,就要走Application了,然后根据布局等等显示闪屏画面(如果有闪屏的情况)
  • T2到T3:闪屏结束了,开始显示首页了,但是实际上从Application(T1)开始,我们可能需要注册很多组件,或者加载很多三方库,这些都是较为耗时的
  • T3到T4:进入了首页,便是开始加载各类网络请求,以及对应的一些弹窗界面(业务需求)

优化方式

如果看懂了上述流程,我们可以理出一些优化点:

闪屏优化

如果禁用了预览窗口,那么用户到T2才能看到闪屏,之前都是桌面,这个体验是非常不好的,尤其是对于中低端机型,这时候可以加一个与闪屏界面相同的主题。

  1. 这块可以对比一下今日头条和小米有品(并无恶意,只是我的手机中这俩app是挨着的),点击今日头条,迅速显示闪屏,小米有品是先白屏在进入闪屏,虽然时间上差距可以忽略,但是对于中低端机型会非常明显(炫耀了一把我的高端手机)
  2. 另一种方式是,将闪屏和首页合成一个Activity,减少一个Activity的耗时,微信这样做后,据说减少了100ms,并未实操,感兴趣的朋友可以试一下。

三方库优化

上面提到了组件注入,以及三方库加载,这个是一个耗时很高的地方,也是一个最大的优化点,合理安排业务,将一些不是马上要用的三方库放到后面再去加载。或者使用懒加载的方式。

但是这里要特别注意一件事,之前遇到了一种情况,讲一个三方库变成了懒加载,但是由于使用的地方太多,一些case未回归,导致个别地方使用的时候未加载成功,所以功能失效了。使用这种方式一定要切记回归case

业务优化

优化业务,为什么说要优化业务呢,启动的每一毫秒都很重要,很多app一启动,会弹出N多弹窗,常见于各类电商软件,这些都是需要预加载的,都是需要时间的,所以这里需要合理衡量业务,砍掉无用的预加载,放到首页加载完成之后再去弹。

还有一些情况,如需要监听首次启动的各类广播,或者其他类型的监听器,当事件触发回调,可能出现大量代码并发。

当然还有其他类型的情况,都是业务太重导致的,这就需要梳理业务,让启动(重要的是首次启动)变得更清晰一些。

还有根据部分业务需求,可能出现在首页加载大的动画,这类需求,需要根据机型进行降级,低端机型低端处理,高端机型高端处理。

线程优化

线程优化包括两个方面,一是优化启动的线程数,这主要是减少CPU的压力。另一方面就是减少子线程和主线程交互时的一些block问题,比如虽然我们把耗时操作放到子线程了,但是主线程执行的一些任务可能等待子线程的锁(或者以回调形式执行),这就尴尬了,尽量避免这种逻辑发生。之前在iOS时发生过类似的事情,启动之后需要根据一个变量判断后续执行,但是这个变量是在子线程赋值的,有时候还会出现同时读写的问题。

GC优化

启动的过程中尽量避免大量的字符串操作,尤其是序列化,反序列化等等,防止出现较多的GC。这时候我们可以尽量复用一些对象,可以频繁赋值,但是不要频繁创建。

I/O优化

在负载过高的时候,I/O 性能下降得会比较快,一定要清楚启动的时候进行了哪些I/O操作,读了什么文件,进行了什么样的网络请求,请求回来什么样的内容,大小是多少等等。如果文件大小内容都是固定的还好,但是可能出现内容不定的情况。如果xx聊天工具,启动的时候需要加载聊天记录,这个文件可能很大,可能很小,需要根据不同情况进行处理。

数据重排

这个思路是之前在网上看到的,感觉很新颖,也记录下来了。这里要先介绍一下linux读取文件的机制。Linux读取文件会以block为单位,一次性在磁盘上读取4kb的内容,并且放到Page Cache中,这时候我们进行读取,实际不会发生真正的磁盘I/O。但是我们可能只有许多零碎的小文件,都是1K左右的,这时候我们可以考虑把数据进行重排,在同一时间需要用的数据放到一个文件中。只要4k以下,是可以一次读取的,不会浪费磁盘I/O的时间。

类重排

这也是一个新颖的概念,我们可以通过重写ClassLoader,看一下启动的过程中类的加载顺序,然后通过FaceBook提供的ReDex进行类重排,将启动过程中用的类往前排。

启动速度.png

iOS


启动分析

iOS的启动分析包含两个部分,一部分是pre-main,一部分是main,这个分类很好理解。

  • main()执行前:加载可执行文件(.o文件)加载动态链接库Objc 运行时的初始处理,包括 Objc 相关类的注册,category的注册,selector唯一性检查执行+load方法,attribute((constructor)) 修饰的函数的调用,C++静态全局变量
  • main()执行后,这个主要包括从main开始到appDelegatedidFinishLaunchingWithOptions中代码执行完毕。从这里开始都是我们自己的代码了,在这里一般是各类三方库的初始化,配置文件读写,首页加载等等。有的监测软件,也会将main执行后的代码以首屏开始加载为锚点,再进行分割,分成首屏渲染前和首屏渲染后。

优化方式

减少动态库的加载

pre-main中有个重要的步骤就是加载动态库,如果动态库过多,可以将动态库进行合并。非系统的动态库,可以支持合并成一个动态库。

减少类

减少加载启动后不需要的类,有时候业务冗余,或者代码年久失修,会有很多类其实不用了,但是仍然出现在工程中,再或者可能几个类能够合并成一个类。

+load优化

+load方法是在main函数之前调用的,遵从先父类后子类,先本类后列类别的顺序调用,+initialize方法是在main函数之后调用的,+initialize方法遵从懒加载方式,只有在类或它的子类收到第一条消息之前被调用的.+initialize只调用一次,init可多次调用。所以少在类的+load方法里做事情,尽量把这些事情推迟到+initiailize

控制C++全局变量个数

这主要是针对在函数外生命的变量,尽量减少这样的声明

业务优化(与android相似)

优化业务,为什么说要优化业务呢,启动的每一毫秒都很重要,很多app一启动,会弹出N多弹窗,常见于各类电商软件,这些都是需要预加载的,都是需要时间的,所以这里需要合理衡量业务,砍掉无用的预加载,放到首页加载完成之后再去弹。

还有一些情况,如需要监听首次启动的各类广播,或者其他类型的监听器,当事件触发回调,可能出现大量代码并发。

当然还有其他类型的情况,都是业务太重导致的,这就需要梳理业务,让启动(重要的是首次启动)变得更清晰一些。

还有根据部分业务需求,可能出现在首页加载大的动画,这类需求,需要根据机型进行降级,低端机型低端处理,高端机型高端处理。

线程优化(与android相似)

线程优化包括两个方面,一是优化启动的线程数,这主要是减少CPU的压力。另一方面就是减少子线程和主线程交互时的一些block问题,比如虽然我们把耗时操作放到子线程了,但是主线程执行的一些任务可能等待子线程的锁(或者以回调形式执行),这就尴尬了,尽量避免这种逻辑发生。之前在iOS时发生过类似的事情,启动之后需要根据一个变量判断后续执行,但是这个变量是在子线程赋值的,有时候还会出现同时读写的问题。

专注于首屏数据

之前的代码中,有这样的逻辑,在加载首屏的同时,还要加载第二屏的内容(TabBarViewController的第二个Tab),这个是没有必要的,如果需要预加载,可以将预加载放到首屏加载完成,可交互之后再去执行。

配置文件读取优化

只加载与首屏相关的内容,其他的配置内容可以放到首屏加载完成后去读取。

充分利用TimeProfiler

在进行首屏数据加载的时候,有很多方法可能造成耗时较长,之前遇到过一个这样的事情,首页加载时间较长,使用TimeProfiler看了一下时间,主要集中在首页图片加载中,首页有很多各式各样的图片,甚至于一些动画,这个时候就要看看耗时主要在哪,比如,UIImage存在延迟解压的问题。+imageNamed这个方法会在加载图片之后立刻进行解压,如果图片过大过大,这个在首屏展示的时候肯定会有性能影响,所以可以考虑使用imageWithContentsOfFile进行异步加载。当然还有其它方法的耗时,需要根据情况进行优化。

三方库优化

与Android类似,很多三方库不一定要在初始化的时候进行加载,需要梳理各类三方库的作用域,将不重要的三方库,放到首屏的viewDidAppear中去加载。这里看似简单,但是是需要认真梳理的,需要扣一下所有的三方库的应用场景,延迟加载会有什么样的影响。

iOS优化建议.png

总结

好了,大致就这些内容,里面很多方法,已经在实际工作中投入使用,还有一些,是对网上主流优化方法的整理,也打算进一步的试用,如果您有更好地方式,欢迎给我留言

推荐阅读:叶紫网

频道推荐
  • 9月,它是唯一卖5毛1斤的蔬菜,每天吃一碗,晒黑的皮肤也能白
    9月,它是唯一卖5毛1斤的蔬菜,每天吃一碗,

    不知道大家和我有没有这种感受,人一到30,每天都害怕自己变的太丑,担心老公不喜欢自己,应该有很多人和我有一样的担忧!而我的担忧去年已经完全消失了,因为我发现一种...

    2019-10-09
  • 网络上颜值很高却买不起的糖果
    网络上颜值很高却买不起的糖果

    网络的带货能力有多强,从许多网红零食上就能够看出来了,说到糖果这种零食,咱们平时一定没少吃,便是小时候常吃的子弹糖果了。而今天要和大家分享的,则是几款网络上最潮...

    2019-10-09
  • 想吃豆腐不用买,教你一把黄豆自己在家做,不用卤水不用石膏
    想吃豆腐不用买,教你一把黄豆自己在家做,不用

    导读:想吃豆腐不用买,教你一把黄豆自己在家做,不用卤水不用石膏豆腐属于最常见的豆制品,营养价值非常高,所以在日常生活当中深受大众的欢迎,豆腐当中不仅含有丰富的蛋...

    2019-10-09
  • 为啥一只活鸭卖50元,而一只烤鸭却只卖18元?原来有“猫腻”
    为啥一只活鸭卖50元,而一只烤鸭却只卖18元

    鸭肉,营养丰富,而且吃起来非常美味,深受大家的青睐。很多人会去买鸭肉自己煮,做法也是非常多种,可以清蒸、焖或者做成盐水鸭等等。买一只活鸭大家都知道,价格并不便宜...

    2019-10-09
  • 饺子包好后,直接放冰箱就“废了”,教你一招,饺子不粘连不开裂
    饺子包好后,直接放冰箱就“废了”,教你一招,

    对于我们北方人来说,饺子是我们的传统食物,以面粉和馅料制作而成,口味独特,口感好,深受大众的喜爱。不同的食材可以制作出口感不同的饺子,而且以煮的方法可以保证食材...

    2019-10-09
  • 寒露后多喝这汤,多做3步,鲜美不腥,每天1碗,皮肤水润不发干
    寒露后多喝这汤,多做3步,鲜美不腥,每天1碗

    怎么样才能熬出味鲜又营养的鸡汤呢?要想熬出来的鸡汤不仅味道鲜美,而且不腥做好3个关键点,鸡汤鲜美,鸡肉滑嫩,孩子也会抢着喝。昨天是二十四节气中的寒露,寒露就是天...

    2019-10-09
  • 你爱吃的蟹棒,究竟是什么?
    你爱吃的蟹棒,究竟是什么?

    蟹棒蟹棒,虽然名字里有蟹,却不是螃蟹肉做的,那究竟是什么又是怎么做成呢?今天就带你一探究竟。▐ 原料切割搅拌蟹棒并不是由纯螃蟹肉制作而成的,它的主要原料是黄线狭...

    2019-10-09
  • 拔丝香蕉零失败做法,掌握好这几个技巧,想不好吃都难
    拔丝香蕉零失败做法,掌握好这几个技巧,想不好

    现在香蕉在我们日常生活中最常见。日常中香蕉是作为水果供大家食用的,而且香蕉的营养也是非常丰富的,香蕉果肉的营养价值颇高,含有丰富的碳水化合物,蛋白质,脂肪,以及...

    2019-10-09