南昌做网站建设公司广州建站费用
南昌做网站建设公司,广州建站费用,怎样收录网站,网站建设制作需求这篇文章会分享小厂如何做包体积优化相关主题#xff0c;涉及内容包括#xff1a;1) Android包体积优化的一种可能是比较标准的推进做法#xff0c;2) 大致流程的心路历程和思考方式#xff0c;3) 如何去总结和分享你们进行过的包体积优化项目。本文不仅仅是一篇分享#… 这篇文章会分享小厂如何做包体积优化相关主题涉及内容包括1) Android包体积优化的一种可能是比较标准的推进做法2) 大致流程的心路历程和思考方式3) 如何去总结和分享你们进行过的包体积优化项目。本文不仅仅是一篇分享还是我个人比较喜欢的总结报告写法。 一、前言
移动 App 特别关注投放转化率指标而 App 包体积是影响用户新增的重要因素而 App 的包体积又是影响投放转化率的重要因素。
Google 2016 年公布的研究报告显示包体积每上升 6MB 就会带来下载转化率降低 1% 当包体积增大到 100MB 时就会有断崖式的下跌 。对于应用商店普遍有一个流量自动下载的最大阈值如 应用宝下载的app超过100M用流量下载时会弹窗提示用户是否继续下载这对下载转化率影响是比较大的。
现在流量虽然变得更廉价一点但是用户的心理是不会变的当 App 出现在应用市场的相同位置时包体积越大用户下载意愿可能越低。
而且包体积或直接或间接地影响着下载转化率、安装时间、运行内存、磁盘空间等重要指标所以投入精力扫除积弊、发掘更深层次的体积优化项是十分必要的。 某手 1M 一年kw级推广费 某条极速版 Google 2016 年公布的研究报告显示包体积每上升 6MB 就会带来下载转化率降低 1%当包体积增大到 100MB 时就会有断崖式的下跌。通过插件化将常规优化后达 120M的包体积降到了 13M 左右最小版本降至 4M包体积缩小至原先的 3.33%。 某德 包体积大小是俞xx直接拍的就要求 x年x月x日 前削减到100M。 某淘 包大小做得比较“霸权”“独裁”新业务超过 1M 要总裁审批一般在平台组都卡掉了。 二、评估优化需求
在开展工作前我们首先得先有两点判断
是否需要进行优化优化到多少算符合预期
那具体应该如何进行判断呢有个比较简单的方法就是对标找到对标对象进行对标。
对于小厂来说一般对标对象有
竞品App业内人气App
基于对标对象我们可以粗略的有如下判断
如果我们App跟竞品App包体积差不多或略高那就有必要进行包体积优化。优化到跟业内人气App中包体积最小的那一档差不多即可。
上述判断还是基于用户视角假如你的 用户需求 比较简单好几个app都可以满足 你会安装200M的产品还是50M的产品。再有假如用户在App商店无意间看到你们的App有点兴趣体验体验但是看到包体积是200M他有多大概率会继续下载换成50M呢
三、包体积优化基本思想
我们在做包体积优化前一定要定好我们的大方向我们怎么优化能做哪些哪些可以现在做哪些没必要现在做
1. 抓各个环节
我们最终是要优化App的包体积那么App包组成部分有哪些我们针对每一个部分去研究如何减少其体积就可以达到我们最终的效果。
2. 系统化方案先行再来实操
优化Android包体积这个事情有一定的探索性但是很多内容或者说手段都是业内在广为流传的既然如此我们应该总结业内可优化手段并逐一进行分析研究是否适合你们App是否需要应用到你们App。如果没有方案的埋头扎进去往往会因为陷入细节而丢失了全局视野。
3. 明确风险收益比及成本收益比
方案与方案之间是有区别的。如果一个方案能减少包体积2M但是线上可能会崩溃你会做吗 如果一个方案能减少包体积2M但是开发成本要一个月你会做吗
4. 明确指标以及形成一套监控防劣化体系
干任何一件以优化为目标的事情时一定要明确优化的指标我们要做App的包体积优化那么我们的指标为减少App安装包 apk 的大小。
当我们指标明确之后我们还需要对现有指标进行监控这样有两个好处
明确优化收益防止劣化
那我们就可以在某个关键的时间节点进行包体积的统计和上报一般时间节点有
App发版打包时粒度更粗开发分支有新的 commit 合入时粒度更细
两种粒度各有各的好处但是目标是一样的
监控每次打包的包体积可以行成指标曲线进行持续观察在包体积增加超出预期时进行及时报警
5. 把包体积这个指标刻在脑子里
自动化能发现已经发生的问题但是把包体积这个指标刻在脑子里能避免问题的发生。
四、自家App包体积一览
1. Android Apk结构
APK 主要由五个部分组成分别是
Dex.class 文件处理后的产物Android 系统的可执行文件Resource资源文件主要包括 layout、drawable、animator通过 R.XXX.id 引用Assets资源文件通过 AssetManager 进行加载Libraryso 库存放目录META-INFAPK 签名有关的信息 2. 你们Apk各个部分都长啥样长多大
这里选取示例App某个版本的安装包来做举例分析下面是包结构图 浅浅分析一波包内内容 五、优化方案草案
通过调研业内常规、非常规手段以及结合你们App的包体积现状可以提前对优化包体积做出比较详尽的可实现、低风险、高收益方案注意这几个点非常重要
可实现 - 可实现可以简单理解为实现成本低一般各种性能稳定性指标都是循序渐进的推进所以往往一期优化时选的实操方案都是实现成本比较低的这样能相对快速的得到比较符合心里预期的优化效果。低风险 - 线上风险必须控制在可接受的程度这里的风险不仅仅是说App运行的性能稳定性风险还需要判断是否会增加线上问题排查的难度当然还会有其他的我没提到的风险项。高收益 - 不解释
所以基于我们需要的是可实现、低风险、高收益的方案我们可以基于上面我贴的APK案例来大致预演可能会采用哪些方案
1. 缩减动态化方案内置代码包、资源包
一般的小厂都会比较大量的采用如RN、H5等动态化方案不可避免的App内就会有一堆内置文件我们看到我们示例的App中RN内置包占了整个包体积超过 30%。当出现这种情况时可以针对内置代码包、资源包单独立子项去推进。
那么如何进行推进呢有同学就会说了业务方不让我把这些玩意儿从APK里面删掉说影响他们打开页面速度影响页面打开速度就会影响一级指标影响收入。
这时为了说服业务方我们就得拿出一些证据用来证明内置包的全部移除或者部分移除并不会对业务产生影响或者说影响足够小。那就可以采取如下一些推进步骤
明确全部内置包或者部分内置包不内置的影响假如内置包是 RN 的页面bundle那给业务方两个数据基本上就能够说明影响 页面bundle现下比例假如因为本地没有内置的bundle打开页面需要同步进行等待下载完成才能加载的话现场下载比例是个比较有说服力的数据。线上bundle更新耗时我们可以统计用户启动App后的一段指定时间90分位能下载多少个bundle50分位能下载多少个10分位、5分位能下载多少个来告诉业务方老用户、新用户、老用户新登录等各种场景到达业务页面的时候有多少比例的用户能完成bundle更新。 明确什么样的资源需要内置同样用RN页面bundle举例假如App的首页就是RN页面那这玩意儿就必须内置了假如一个页面在犄角旮旯日pv才不到100那就完全可以不需要内置。给出内置资源名单拿着内置名单和上面明确的不内置影响统计找业务方拉会 这一步最好是从上往下进行推进而不是同级推进
2. 分架构打包
分架构打包能减少libs文件夹体积libs文件夹里会包含不同架构的 so 库集合。
首先我们最终apk包是要上传到应用商店的应用商店得支持双包上传。答案确实是支持且应用商店推荐双包上传。
Android 官方也是有相关的api支持分架构打包
splits {// 基于不同的abi架构配置不同的apkabi {// 必须为true打包才会为不同的abi生成不同的apkenable true// 默认情况下包含了所有的ABI。// 所以使用reset()清空所有的ABI再使用include指定我们想要生成的架构armeabi-v7a、arm-v8areset()// 逗号分隔列表的形式指定 Gradle 应针对哪些 ABI 生成 APK。只与 reset() 结合使用以指定确切的 ABI 列表。include armeabi-v7a, arm64-v8a// 是否生成通用的apk也就是包含所有ABI的apk。如果设为 true那么除了按 ABI 生成的 APK 之外Gradle 还会生成一个通用 APK。universalApk true}}这里需要注意的是线上并不是所有的手机都支持 64位 的安装包应用商店可以双包上传线上灰度更新可以下发32位的安装包或者是 32/64 兼容包。
3. So 压缩
分架构打包是减少so的数量so压缩是减少so的单个体积。
android:extractNativeLibstrueandroid:extractNativeLibs true时gradle打包时会对工程中的so库进行压缩最终生成apk包的体积会减小。
但用户在手机端进行apk安装时系统会对压缩后的so库进行解压从而造成用户安装apk的时间变长。
若开发人员未对android:extractNativeLibs进行特殊配置android:extractNativeLibs默认值 minSdkVersion 23 或 Android Gradle plugin 3.6.0情况下打包时 android:extractNativeLibstrue minSdkVersion 23 并且 Android Gradle plugin 3.6.0情况下打包时android:extractNativeLibsfalse
4. 大so动态下发
我们能看到有些so库单个体积超大放在apk里就算能压缩压缩后体积仍然很大可能会占到 app体积超过 10%。针对这种情况选择动态下发。 动态下发的so如何进行加载
我们采用ASM的方案对代码中所有的 System.load、System.loadLibrary 进行hook进入到我们自己的逻辑这样我们就可以走下面流程
下载so库解压so库校验so库加载so库
这里需要注意的一点就是当动态下发的so没有下载、解压、校验、加载完之前如果用户进入到了相关的业务场景必须有兜底机制。比如在样例App的场景中使用了 opencv 库来做图片的二维码识别当so没下载下来时要识别二维码就会被兜底到 zxing。
而且由于我们有较好的Hook框架的封装所以我们需要hook时仅仅需要进行配置即可 5. 大文件压缩优化对内置的未压缩大文件进行压缩文件用高压缩率的压缩算法
假如apk里有内置的大文件可以通过对其进行压缩从而减少包体积压缩时可以选用高压缩率的算法。
6. 代码优化
去除无用代码、资源
去除无用代码我们可以用官方的Lint检查工具 去除无用三方库 减少ENUM的使用
每减少一个ENUM可以减少大约1.0到1.4 KB的大小假如有10000个枚举对象那不就减少了14M美滋滋啊但实际上具体还是要看项目代码情况来考虑毕竟不是所有的项目里都有 10000 个枚举。
7. 资源优化
无用资源文件清理
去除无用资源文件可以通过lint工具来做也可以通过微信开源的 ApkChecker来完成。
图片压缩、转webp
图片压缩可以使用TinyPngAndroidStudio也有相关插件官方术语就是
使用智能的无损压缩技术来减少图片文件的大小通过智能的选择颜色的数量减少存储的字节但是效果基本是和压缩前一样的。
图片着色器
相同图片只是颜色不同的话完全可以只放一个图片在内存里操作 Drawable完成颜色替换。
图片动态下发
如果本地有大图且使用要求为未压缩或者压缩之后仍然很大可以适当的选择动态下载该图。
resources.arsc资源混淆
resources.arsc这个文件是存放在APK包中的他是由AAPT工具在打包过程中生成的他本身是一个资源的索引表里面维护者资源ID、Name、Path或者Value的对应关系AssetManager通过这个索引表就可以通过资源的ID找到这个资源对应的文件或者数据。
通过对apk 中的resources.arsc进行内容修改,来对apk进行深度压缩。这里可以采用微信的AndResGuard方案。
8. 三方库优化
移除无用三方库
移除无用三方库需要人肉扫描 build.gradle 文件一个一个的去检查依赖的三方库是否被我们代码所使用。
功能重复的三方库整合
特别常见的caseRN 用的图片加载库是 Fresco客户端用的图片加载库是 Glide他们都是用来加载图片可以通过删除一个库让项目依赖的库少一个。
修改三方库源码不需要的代码进行剔除
XUtils是一个工具大杂烩但是假如我只用它来加载图片其他工具是不是就完全无用可以进行剔除。
9. 去除 DebugItem 包含的 debug信息与行号信息
在讲解什么是 deubg 信息与行号信息之前我们需要先了解 Dex 的一些知识。
我们都知道JVM 运行时加载的是 .class 文件而 Android 为了使包大小更加紧凑、运行时更加高效就发明了 Dalvik 和 ART 虚拟机两种虚拟机运行的都是 .dex 文件当然 ART 虚拟机还可以同时运行 oat 文件。
所以 Dex 文件里的信息内容和 Class 文件包含的信息是一样的不同的是 Dex 文件对 Class 中的信息做了去重一个 Dex 包含了很多的 Class 文件并且在结构上有比较大的差异Class 是流式的结构Dex 是分区结构Dex 内部的各个区块间通过 offset 来进行索引。
为了在应用出现问题时我们能在调试的时候去显示相应的调试信息或者上报 crash 或者主动获取调用堆栈的时候能通过 debugItem 来获取对应的行号我们都会在混淆配置中加上下面的规则
-keepattributes SourceFile, LineNumberTable这样就会保留 Dex 中的 debug 与行号信息。根据 Google 官方的数据debugItem 一般占 Dex 的比例有 5% 左右
10. ReDex
ReDex 是 Facebook 开发的一个 Android 字节码的优化工具。它提供了 .dex 文件的读写和分析框架并提供一组优化策略来提升字节码。官方提供预期优化效果对dex文件优化为 8%
11. R 文件瘦身
当 Android 应用程序被编译会自动生成一个 R 类其中包含了所有 res/ 目录下资源的 ID。包括布局文件layout资源文件图片values下所有文件等。在写java代码需要用这些资源的时候你可以使用 R 类通过子类资源名或者直接使用资源 ID 来访问资源。R.java文件是活动的Java文件如MainActivity.java的和资源如strings.xml之间的胶水
通过R文件常量内联达到R文件瘦身的效果。
12. 可能的更多方案
除了我上面列到的一些市面上还有一些其他的方案有复杂的有不复杂的有收益高的有收益低的大家可以在掘金上搜索Android包体积优化就能搜到大部分了当然在大厂里还会有很多很极致的方案比如
去掉kotlin生成的许多模板代码、判空代码去除布局文件里不需要的冗余内容…
思想是这么个思想大家在实操的时候思路就是先调研方案调研完成之后再选型。
六、基于风险收益比及成本收益比敲定最终实现方案
这一步的重点是明确风险收益比及成本收益比
方案与方案之间是有区别的。
如果一个方案能减少包体积2M但是线上可能会崩溃你会做吗如果一个方案能减少包体积2M但是开发成本要一个月你会做吗
这里我们在示例App的基础上对每个手段进行仔细分析包括 预期效果 成本 风险
就这样当我们制定完成我们的目标方案之后就可以放手干了。
手段预期效果成本是否要做进度备注重点优化项- 缩减RN 内置bundle预期效果177.43M - 114.43M中✅RN 内置bundle缩减xxxx版本带上- 分架构打包64位、32位分开打包预期效果32位117.43M - 71.9M 64位117.43M - 87.6M低✅xxxx- so压缩方案预期效果32位71.9M - 55.5M 64位87.6M - 58.3M低✅xxxx- 大so文件动态下发预期效果32位55.5M - 50.7M 64位58.3M - 51.7M中✅xxxx大文件优化- zip优化对内置的压缩文件替换压缩算法预期针对 assets 文件❌针对不同类型文件选取不同高压缩率算法代码优化 (dex文件为 15.6M)- 去除无用代码Android Lint✅xxx- 减少ENUM的使用全部代码 enum类 一共60个就算全删了也只是减少 84k✅xxx每减少一个ENUM可以减少大约1.0到1.4 KB的大小资源优化 (目前res目录大小为 6.3Memoji目录大小为 770k)- 无用资源文件清理Android Lint✅xxx用ApkChecker再跑一次- 图片压缩、转webpTinyPng✅xxx- 图片着色器✅xxx- 图片动态下发主要是针对比较大的图实际上经过TinyPng 压缩后图片大小已经大大减小✅xxx- resources.arsc资源混淆AndResGuard两年不维护花了一小时没完全跑起来但看到了大致优化效果1.3M - 920k❌github.com/shwenzhang/…三方库优化 (dex文件为 15.6M)- 移除无用三方库✅检查一下- 移除无用三方so库✅- 功能重复三方库整合✅- 修改三方库源码不需要的代码进行剔除✅
七、确定优化效果
当我们进行了一系列的或大或小的改动之后如何描述最终优化效果给两张对比图不就行了无图言X。 八、总结
大家在进行一些有挑战性或者是比较有意义的项目时其实可以多进行总结总结的好处有什么我就不多解释了懂的都懂哈。
比如我们这里可以装模作样的这样总结一下
做的好的方面
足够系统化前置调研足够充分风险、收益、成本考虑足够充分各方面沟通足够充分优化决心足够大
也可以告诉自己及读者几句话 这是一个系统的需要持续去投入人力的事情万万不可有了一定结果之后放松警惕 别人能做的我们也能做只要有足够的决心去做 做事不能太讲究所谓的方法论不然会掉入陷阱但是确实要讲究方法论 有些事情你做好了可能仅仅是因为做这个事情的人是你如果是别人来做也能将这件事情做好
九、展望
一般来说进行总结之后都得来一些展望给未来的自己挖点坑给总结的读者画点饼。比如我们这里就可以这样继续装模作样的展望一下
上面已经反复提及了当前这一期的优化工作重点考量的指标是风险收益比及成本收益比所以一些极致的或者成本收益比较高的优化手段并没有被采用所以后续还是有很多事情可以深入的干下去。 resources.arsc资源混淆 去除 DebugItem 包含的 debug信息与行号信息 ReDex R 文件瘦身 So unwind 优化 kotlin相关优化 …
十、真正的总结
这里我就发散性的随便总结下吧。。。也不深入纠结了。
包体积优化是个庞大的工程项目不仅仅需要优化还需要防劣化优化过程中还会涉及到业务冲突说白了就是某些东西从APK包中移除了或多或少会有些影响还需要去跟业务方达成意见一致。大家不管在做什么优化课题时最好是分步骤分工期的去进行不要一口吃成胖子如果上来就追求完全极致的优化效果往往会带来两个负面风险1) 优化工期拉长时间成本成倍增加2可能影响线上App或者线下各种工具的运行稳定性。系统化的调研、成本 风险 收益的总和考虑非常重要任何优化项目开始进行或者进行过程中都需要牢牢的印在脑子里每日三省你身。遇到困难不要畏惧各种优化项目往往会遇到很多阻力比如方案实现太难、业务沟通太难等等一块石头硬磕磕不动的时候换个方向磕换方向也磕不动那就换块石头磕比如假设业务方沟通不动那就换个角度把你和业务方放在同一角色上给业务方找收益或者。做的项目是啥或者说研究的方向是啥其实不是最重要的我们这种普通程序员更重要的是解决问题的能力因为你们做的事情换个人用同样的时间成本或者更多的时间成本往往也能做好所以是你做好的这件事情其实没那么重要更重要的是遇到其他问题或者有其他的疑难杂症和系统性问题时知道你一定能做好。
Android 学习笔录
Android 性能优化篇https://qr18.cn/FVlo89 Android Framework底层原理篇https://qr18.cn/AQpN4J Android 车载篇https://qr18.cn/F05ZCM Android 逆向安全学习笔记https://qr18.cn/CQ5TcL Android 音视频篇https://qr18.cn/Ei3VPD Jetpack全家桶篇内含Composehttps://qr18.cn/A0gajp OkHttp 源码解析笔记https://qr18.cn/Cw0pBD Kotlin 篇https://qr18.cn/CdjtAF Gradle 篇https://qr18.cn/DzrmMB Flutter 篇https://qr18.cn/DIvKma Android 八大知识体https://qr18.cn/CyxarU Android 核心笔记https://qr21.cn/CaZQLo Android 往年面试题锦https://qr18.cn/CKV8OZ 2023年最新Android 面试题集https://qr18.cn/CgxrRy Android 车载开发岗位面试习题https://qr18.cn/FTlyCJ 音视频面试题锦https://qr18.cn/AcV6Ap
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/89040.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!