app冷启动速度如何优化?app冷启动速度优化的流程
1. 背景
App的启动速度极大影响到用户体验,启动又分为冷启动、热启动和温启动三种,冷启动是从零创建进程并完成初始化的过程,是三种启动方式里面挑战最大的,而且优化了冷启动速度,也能间接优化其他启动方式,业界一般说的启动速度优化指的就是冷启动速度优化,因此本文亦专指针对app冷启动速度的优化。
(相关资料图)
2.问题分析
首先需要定义问题,相信大家都有这样的体验,如果给你一个工程代码,然后问你该如何优化?至多能看出代码结构上面的问题,比如某几个模块耦合比较严重,不利于维护;存在很多重复代码,代码的工程结构划分不够合理;而对于性能问题,则是看不出要如何优化的,因为性能问题依赖于代码的执行,工程代码总是要依赖于系统的框架才能正常跑起来,比如安卓app代码总要受限于系统提供的组件application、activity、window、service等等,引用的第三方库比如网络框架、缓存框架等,它们运行的快慢对我们来说也是不透明的。所以,单纯的看代码来进行优化是行不通的,需要结合系统框架来画出整个的执行顺序图。 上图是结合app自身业务,简单描述了从手机桌面点击icon图标开始到首页加载的整个流程,同时标注了每个阶段对应的界面,也就是用户可感知的部分。整体流程图按照执行顺序一共分为三个阶段: 1、进程启动:主要是完成各个模块包括第三方sdk的初始化,界面上对应于启动页,此界面可配置,几乎所有的应用都有这个页面。 2、闪屏加载:负责自有广告和第三方广告的加载展现,界面上对应于闪屏页,绝大多数app都有这个界面,一般和自身业务关联不大 3、首页加载:完成自有业务数据的加载展现,界面上对应于app业务的首页,是真正涉及到自身业务的界面 这三个部分在界面上都有体现,哪部分代码执行耗时,就会造成相应的界面展现变慢,切换界面存在突兀、不流畅的情况。 由于启动页是系统为了优化用户体验,允许第三方应用在进程启动时配置的一个界面,不能算是真正的自有界面。首页用户最先看到是卡片数据的展现,因此,为了便于问题的解决我们将整个流程分为两个步骤来优化: 1、从桌面点击到广告页的展现优化2、首页数据展现优化
3.1 从桌面点击到闪屏页的展现优化
如上图所示是这部分的代码执行情况,整个图中间的横轴是时间轴,上部分属于主线程操作,也是用户可见的部分,下面的部分属于子线程操作对用户不可见。 启动页部分:一部分必须要在主线程进行初始化,另一部分则放到了子线程进行初始化。 闪屏页部分:灰度、账号、闪屏等数据的请求处理和闪屏数据的页面展示,而且页面展示部分也已经进行了缓存优化 单独看这两块儿其实都已经进行了优化,直观上可优化的空间很小,此问题是否存在更优解?不得而知,一时陷入了僵局。但是看看手机里其他的app,比如今日头条启动速度真的是很快, 现在回到问题的出发点:我们的目标就是让启动页展示时长越小越好,让闪屏页以最快的速度出现。其实就是将主线程操作尽可能的移到子线程,尽管一个方法执行几十毫秒,但是积少成多想必能优化不少,只能硬着头皮去试验了。 启动页优化启动页展示时间长短主要受进程初始化中主线程各模块的初始化影响,子线程初始化模块是不影响界面加载时长的(前提是子线程的优先级设定为低于主线程,否则还是会影响)。当前简单的将进程初始化分为主线程模块初始化和子线程模块初始化是不够的,可以将划分的粒度进一步细化,比如我们可以充分利用闪屏页展现的过程,尽可能的将一些不必要立即初始化的模块进行延迟初始化,将一些不能一刀切延迟初始化的模块在该模块第一次使用的时候进行初始化。经过这样的划分得到如下结果: 主线程初始化:进行简单的赋值操作如Context、手势密码设置和初始化ARouter,优化获取进程名称实现方法,将原io方式改为 内存读取方式 延迟初始化:主要是一些第三方sdk进行延迟初始化 用时初始化:gio初始化配置、数据库初始化加载、安全校验等使用时初始化避免进程启动抢夺资源 子线程初始化:将数据库、推送、bugly、abtest合并在同一子线程处理,避免开启线程过多,造成cpu拥塞 闪屏页优化闪屏页优化主要是将灰度、账号、闪屏等数据处理从主线程尽量挪到子线程 现在已经对启动页和闪屏页两部分分别进行了最大可能的优化,理论上来说启动速度应该会提上去,通过 adb shell am start -W闪屏页 测试发现启动速度确实提上来了,而且还很明显达到了600-700ms左右,这个结果还是非常明显的,而且也基本达到了预期。但是和头条进行直观对比发现,广告显示的速度还是比头条慢了半拍,头条几乎是瞬间加载。 现在的问题是:进程启动速度上来了,但是广告展示还是慢一点。首先分析当下广告的加载流程:读取磁盘图片到内存然后设置到view进行展示。如何才能加快这个步骤呢?这个步骤本身已经没有什么可简化了,图片必须要经历从磁盘到内存的加载过程。经过一番思索和分析,一个想法浮现出来: 可以将图片的加载提前,不一定非要在广告界面展现的时候才去加载,可以在进程初始化的时候就开始在子线程进行加载,加载完成后将drawable转交给主线程。回调方式采用观察者模式实现,既保证了加载和展现的松散耦合,也能保证时效性。实现方案如下: OnLoadResultListener是观察者接口,如上图所示。 观察者回调处理逻辑如上图所示,整个加载过程只执行一次,等到界面成功注册到预加载服务,并且预加载完成时,就将结果返回给界面展示。 运行代码然后查看加载效果,已经和今日头条的效果差不多了。至此,第一阶段的优化全部结束。基于小米8 lite手机对App新旧正式版通过 adb shell am start -W闪屏页10次测试结果如下,从均值来看大概提升了3.33倍 小结对整体的优化流程总结如下图所示,对比之前的现状图可发现:青绿色部分进程初始化逻辑一分为四,只在用户可见的主线程执行最必要的初始化;其余部分则要么转移到子线程,要么延迟处理或者用时处理。粉色部分闪屏业务逻辑一分为二,一部分提前到了主线程启动页,另一部分转移到不可见的子线程处理。
3.2 首页数据展现优化
常规做法是针对这些数据进行预加载,然后展示即可,但是首页的数据往往和其他模块间存在耦合,在多个界面展现,如果只是修改首页会引入更多问题,比如数据不一致,维护困难,不仅没有降低问题的复杂度,反而将问题的复杂度又提升了一个层级。所以针对这类业务,首先要看目前设计的架构是否合理,是否便于优化,如果不满足,则先要优化架构,然后才能去优化性能,否则得不偿失。 数据管理优化先分析当前这几类数据的业务结构,如下图所示: 从图中可看出各个模块各自为政,单独处理数据,造成了很深的业务竖井,只改变一个地方,很容易造成数据的不一致。为此需要改变原来面向模块划分业务的方式,改为面向数据服务的方式,打破业务竖井,整个工程同类型数据只维护一份,为各个业务所共享,各个业务模块则变得简单、轻量化,只局限于ui部分。优化后的效果如下图: 限于篇幅,最终实现的代码不再展示,将最终的类图框架展示如下,该框架有以下特点: 1、易用性好,该框架以工厂模式的方式提供给外部使用,入口统一; 2、可读性强,采用状态模式完成缓存、网络、加载中三种不同的状态下的数据处理逻辑,避免重复请求; 3、扩展性好,对于新的业务数据只需要继承自DataProvider即可; 4、可维护成本低,将数据和界面完全解耦,只需要很小的修改就能优化性能、更改业务规则,事半功倍。 首页加载优化正是有了前面重构的基础,所以这部分优化变得非常简单,只需要两步:1、将数据初始化放在进程启动的子线程中去做预加载处理;2、然后在首页直接做数据获取操作即可。就能让首页的直接显示缓存数据,而不是重新发起数据加载
4 优化的一般流程
对app优化的一般流程进行总结如下
4.1 弄清现状
严格按照实际的执行流程画出执行流程,特别注意需要分为用户可见和不可见两部分进行区分,这样才能站在用户的角度来指导后续优化的取舍。
4.2 架构先行
对业务模块进行优化前,一定要分析是否要重构。因为让正确的代码更快比让快速的代码正确要容易的多,否则的话,只会将问题进一步复杂化。
4.3 操作手段:
空间换时间缓存就是典型的应用场景。 充分利用多线程由于ui操作都在主线程,为了用户体验流畅,一定要尽可能的将耗时逻辑放在子线程,子线程一定要设置优先级 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND),不然新创建的线程优先级默认和主线程相等,会和 主线程旗鼓相当的争抢CPU资源。 延迟懒加载站在使用者角度优先加载用户首先体验到的业务,其他业务可以延迟或者使用时再加载。 打破业务间藩篱用户看见的并不是全部的真相,闪屏展示的时候也可以充分利用这段时间去加载其他业务。
5. 写在最后的话
实践的过程是螺旋上升式的,有暂时的迷茫,有百思不得其解的困惑,心情总是处于惊喜—失望—平静的反复切换中。 手机里的所有app都是竞品,都在抢夺用户的时间,竞品的优秀表现省去了我们对做某件事“行不行”、“做不做”的探讨,而是直接去思考“如何行”、“如何做”。 根据实践经验和个人理解促成此文,不足之处在所难免,欢迎批评指正。
标签:
相关推荐:
最新新闻:
- app冷启动速度如何优化?app冷启动速度优化的流程
- 世界简讯:中国工商银行:U盾签名失败的解决方法
- 深信服捕获勒索病毒Megacortex新型变种 免费查杀 当前热门
- 迅雷怎么离线下载?迅雷离线下载与高速通道运作原理详解_热议
- 全局消息钩子代码 火苗999℃的博客代码_当前动态
- 环球快报:基于Tcl的自动化脚本语言——HammerOra
- 杀毒软件有哪些推荐?2013八大免费杀毒软件排行榜
- 国际最先进的全数字视频无压缩传输技术——2路数字光端机系列
- 如何使用LaTex编写数学公式?LaTeX使用技巧 天天即时看
- 科密碎纸机怎么样?科密碎纸机的价格及特点_全球热闻
- 环球新动态:山寨机怎么刷机?山寨机刷机注意事项
- 天天新动态:高频逆变电源是什么?高频逆变电源的应用领域及注意事项
- 软件安装和系统维护的原则是什么?电脑维护操作及遵循原则介绍
- 快看:如何利用主板进行超频?主板超频全解析
- 惠普免费在线数码相片冲洗馆 惠普喀嚓鱼的优点介绍
- PSP3000的635/639PRO-B7下载及安装教程_全球即时
- 天天快资讯丨地采暖怎么样?地采暖优缺点介绍
- MOTO XT615的手机系统是什么?摩托罗拉新UI界面设计_环球时快讯
- 快消息!vista系统怎么重装?vista系统重装下载安装教程
- 载乐网络科技创始人王自如——ZEMobileER-当前消息
- CE是什么缩写?CE是什么含义?
- 小时代3刺金时代好看吗?电影《小时代3.0刺金时代》剧情介绍
- 酷派W706怎么样?有哪些优势? 世界即时
- 即时看!跨站脚本攻击是一种代码注入攻击
- 剑灵配置要求是什么?《剑灵》1024x768游戏介绍|天天资讯
- 快消息!onekeyghost安装器一键还原重装电脑系统
- 当前视点!狄拉克:量子场论的研究方法
- 自学编程看什么书?10本入门编程书籍推荐_天天微动态
- 美的电饭锅怎么样?美的电饭锅价格及特点介绍|前沿资讯
- 宏碁商务电脑有哪些特点?宏基台式机介绍
- 粒子群算法原理 基于numpy6.2的粒子群算法详解 当前资讯
- 电脑杂谈:oppor9s手机参数大全
- 蒙特利尔的麦吉尔大学:计算几何课程资料
- 【全球快播报】面试后说hold什么意思?外国人说“You have my word”什么意思?
- 当前资讯!液晶显示背光板生产厂家有哪些?背光板生产厂家详情介绍
- 《黑豹2》明日上映 漫威:接收全方位炸裂视效冲击!
- java面试专题:RPC源码深度剖析
- 经典摔角综合格斗游戏 《周末勇士》登陆steam:全球微速讯
- 什么是驱动程序?驱动程序和光驱有什么区别?
- 电脑怎么贴膜?电脑贴膜防辐射吗?
- 百度输入法如何自定义个性短语?百度输入法个性短语设置
- 10套极好用的PS绘画笔刷工具 简直就是神器
- EastFax传真原理是什么?EastFax传真原理介绍
- 苹果新系统OS10.3正式版评测:自动转化到新文件格式_环球今头条
- 优秀的企业绩效考核系统——MVC设计模式
- sqoop导入pg11常见问题及解决方法 热点在线
- java代码实现二分法查找 二分法的实现:每日消息
- 为什么要拆机?联想U310拆机教程:环球头条
- 天天视点!如何登录新浪微博html5?新浪微博怎么登陆?
- 金士顿u盘哪家好?士顿u盘厂家推荐:热点评
- 杀不死的「去中心化」:每日速读
- 2023年,我们需要怎样的企业家精神:世界快消息
- iPhone 14 Pro全系降价700元:苹果坐不住了
- 要闻:腾讯成立职业技能培训学校公司 注册资本100万元
- 2023年中国汽油行业市场供需现状分析 汽油出口金额创历史峰值【组图】_天天快资讯
- 焦点资讯:男子礁石上钓鱼被海浪拍进石缝 垂钓别选偏僻海域
- 环球头条:2万元的iPhone上热搜 网友:不是它疯了就是我疯了
- 环球通讯!世嘉发布神秘手游新作先行预告 2月10日正式公布
- 生活逃不过科技与狠活:世界视点
- 特斯拉又出事故 高速撞车 每日焦点
- 每日热门:微软Bing已经引入ChatGPT 搜索市场要变天?
- 比尔盖茨约马斯克做慈善家:咱们把钱全捐了-环球观天下
- iPhone 14到手4899元 史低价快来捡漏 报道
- 《阿凡达:水之道》导演卡梅隆diss流媒体:观众需要回到影院去!
- 葛优起诉哔哩哔哩网络侵权:答辩期及举证期满后第3日开庭审理。-世界时讯
- 全球微头条丨生存恐怖游戏《原始预兆》新预告 红发美女打恐龙
- RTX4070 Ti比A卡低了60W功耗 4年能省2300多元
- 环球快看:日本政府否认雨宫正佳将接棒央行传闻,日元反弹
- 四川地下皇帝:400亿黑财帝国覆灭记
- 每日热讯!为什么三体不稳定,我们的太阳系如此稳定?
- 主播说联播丨满目春光,满怀希望,奔向美好!
- 路痴党福音!《星战绝地:幸存者》有快速旅行
- 天天观速讯丨男子油锅炸元宵现场惨烈 网友:需要穿防护服操作
- 全球头条:《卧龙:苍天陨落》新演示 大战魔化武将颜良文丑
- 《死亡空间:重制版》暂未打算支持Mod或加入新难度模式-热点