简介:包大小增量分析

作者:闲鱼技术-金喏

1.背景

  不知大家是否注意到,闲鱼的包大小在随着服务用户的增多和新业务的持续迭代不断增长。在过去的半年时间,Android端包大小涨了43%,iOS端也涨了26%,若再不加管控,按照目前的增长速度再过1年可直逼200M。
  包大小对应用的下载转化率和留存率起到至关重要的作用,瘦包作为闲鱼技术今年的重点项目,意义非同凡响。
  对于闲鱼来说,瘦包能提升应用的下载转化率。首先是苹果公司不支持流量下载超过200M的包,包越大下载时间越长失败率越高,且据Google play统计,包大小每增加6M,下载转化率会下跌1%。此外也能提升用户的留存率,因为当用户手机内存不够用时,肯定是优先删除占内存比较大的app。
  对开发来说,定期清理废弃代码、不用的SDK和整理重复的资源,有助于提高代码的健康度和架构的合理性。
  但随着每一次客户端发布,业务导致的增量使包大小默默攀升。业务需求是要做的,包大小也是要控的,为了让每一次新需求集成时,开发们能切实感受到对整体包大小的影响,让每一次包大小变动都有迹可循,需要对包大小进行科学分析。
  现在开发每次提交代码后,会触发打包平台自动打包,包构建成功后会自动进行包对比分析,并发回开发包增量分析报告邮件。在介绍这个包增量分析工具之前,先给大家科普下安装包的构成。

2.安装包构成

2.1 Android包构成

  Android安装包是以后缀名为“apk”的压缩包。闲鱼安装包解压后的主要构成如下:
  AndroidManifest.xml 配置文件:包含包名、组件、权限的配置信息等。
  resources.arsc android资源索引表:包含资源名称、类型、值、ID和配置信息。
  classes.dex :是很多.class文件处理后的产物,最终可以在 Android 运行时环境执行。
  /assets :放置随包打入的文件,如text、二进制数据等。
  /res 资源文件:存放图片、字符串、布局文件、xml文件等,运行打包时没有使用的文件资源不会打入包中。
  /lib :程序运行时依赖的库。

2.2 iOS包构成

  iOS安装包是后缀为“ipa”的压缩包,解压后主要包含以下几部分:
  签名文件:里面的CodeResources包含对bundle中的所有资源文件的签名信息。
  资源文件:程序运行过程中需要的资源,比如图片、音频、视频、nib文件、配置文件等。
  可执行文件:是通过编译器、连接器将我们编写的代码、静态库、动态库编译成的文件,是程序的主体。其中静态库在链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝,动态库则是链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序共用。
  bundle文件:工程中使用的其他第三方或资源的bundle。

3.包分析方案

3.1 Android包分析

  apk压缩包按照资源文件类型分类,主要有:so资源(程序运行依赖的库,如接入UC浏览器内核SDK时,引入的so达到惊人的12M)、图片资源(png、webp、jpg等)、Java代码(dex文件)、xml代码这几类,此外还可横向统计flutter相关资源情况。
  由于可以拿到单个文件的信息,所以我们开发了工具解析apk包中的内容,从文件类型角度分析包资源占比情况,以及将资源文件按照大小排序展示,并以图表形式直观告诉开发资源情况。

3.2 iOS包分析

  我们现在是从静态库、动态库、资源维度来分析包内容和增量。

3.2.1 静态库大小

  通过分析link map文件获得静态库大小,网上有很多link map的解析工具。核心是解析link map文件中的Object files和Symbols中的数据。

#Object files:
[  0] linker synthesized
[  1] /Users/xy/build/workspace/Pods/MNN/MNN.framework/MNN(MNNReluInt8-24695ca527c0186b07.o)
[  2] /Users/xy/build/workspace/Pods/MNN/MNN.framework/MNN(MNNGemmInt16to32_4x4_Unit-416f183fdf349b160b82.o)
[  3] /Users/xy/build/workspace/Pods/MNN/MNN.framework/MNN(CPUPermute.o)

  每一行代表对应可执行文件的编号,如CPUPermute.o文件编号是3。

#Symbols:
#Address   Size        File  Name
0x100006CA0 0x000000EC  [  3] __MNN10CPUPermuteC2EPNS_7BackendEPKNS_2OpE
0x100006D8C 0x0000004C  [  3] __MNN2Op15main_as_PermuteEv
0x100006DD8 0x00000008  [  3] __MNN10CPUPermute8onResizeERKNSt3_$body
0x100006DE0 0x00000580  [  3] __MNN10CPUPermute9onExecuteERKNSt3_$body
0x100007360 0x00000034  [  3] __MNN38___CPUPermuteCreator__OpType_Permute__Ev
0x100007394 0x00000070  [  3] __MNN10CPUPermuteD1Ev

  在Symbols部分,Address是偏移地址,Size是所占内存大小,File所指的编号就是Object files中的文件编号,将Symbols中所有相同编号的Size累加起来,即可获得该编号对应可执行文件的大小了。
  然后根据可执行文件的目录信息,可知该文件所属的静态库,从而计算出对应静态库代码大小。此外静态库大小在计算时需要排除对应的dead Stripped Symbols 的大小来获得真正的二进制大小,因为这些是无用的符号,链接的时候不会加入。

3.2.2 动态库大小

  动态库通常位于安装文件根目录下的Frameworks目录中,通常是一个后缀为.framework的文件夹。
  由于动态库在arm64架构下比较大,且苹果在拆包阶段会将打包好的通用的主二进制和动态库拆分成单架构的主二进制和动态库,所以只要是涉及二进制只计算arm64单架构的情况即可。
  动态库大小是直接用lipo 拆成arm64单架构大小后计算framework文件夹占磁盘大小获得。

3.2.3 模块大小

  模块大小为库大小+该模块所有资源文件占磁盘的大小,若为动态库的模块,则资源大小仅计算拷贝到主bundle的资源。分析结果如下图所示:

3.需求增量卡口

  瘦包主要靠开发努力,要让大家在平时开发中有瘦包的意识,最好有工具能让开发在日常开发中清楚知道每个文件/模块的大小,切实感受到需求集成后对整体包大小的影响和相关文件/模块变动情况,从而促进开发进行相应的优化。

3.1 增量自动分析

  通过将前面介绍的包分析能力集成到打包脚本,在每次包构建成功时,也会同步产出基础的包内容信息,再通过进一步的分析后获得包中每个文件/模块的大小情况。当代码改动触发重新打出新包后,文件/模块通过一一对比的方式,找出哪些有新增,哪些被删除,哪些内容发生变动,以及变动产生的大小,并产出对比报告邮件。通过这样的方式让开发对代码增量有一个直观感受。
  那如何让包增量分析工具能在日常开发中持续稳定发挥作用呢,接下来介绍闲鱼的需求增量卡口设计。

3.2 增量卡口设计

  在之前,闲鱼的包大小差异通常都在拉出集成分支,打出版本release包时才发现,经常会震惊于这个版本的包又比上一个版本要大几M,然后再紧急去寻找是什么需求集成导致的巨大增量。但这时发现包大小的问题已经非常滞后了,版本马上就要发布,这个时候即使抓到了剧增的源头,也很难在短时间内进行优化。
  因此需要增加需求集成卡口,测试通过后在合入主分支之前,经过包增量确认再集成,而不是在集成后打出release包时。现在的做法如下,开发只需要提交代码,即可自动获得包增量分析报告。

  其中包增量对比邮件内容,会包含与主分支最新构建、当前分支前一次构建,当前分支最初一次构建包的包大小和增量的对比结果。此外为了数据的准确性,需要开发在拉出开发分支后先构建一个基准包,并在提测和集成前合并一把主干,这样报告数据才会更准确。

  最后是提测部分,开发同学发送提测邮件时需要标注本次提测包增量及图片压缩情况,若需求增量大于100K,根据超出范围情况,需要备注原因和老板确认。bug修复期间不免也会有代码改动,在测试完成后集成前,会再确认一次包增量情况再集成。

4.效果与展望

  闲鱼需求增量卡6.20正式上线至今半月,7个客户端新需求都收到了严格的卡口洗礼。以iOS为例,这半个月主干分支包大小不增反降0.5M,在开发过程中,开发也开始有意识通过优化老业务代码和资源,为新需求增量挪出空间。
  需求增量卡口只是长效控制包大小的一个手段,加强开发在日常编码中的瘦包意识,让每一次需求都有迹可循,此外对于存量的资源、业务代码清理等手段也在有序进行,flutter产物更精细的分析方案和有效的瘦身方法也在持续探索中,期待小胖鱼早日瘦身成功吧~

原文链接:https://developer.aliyun.com/article/766949?

版权声明:本文中所有内容均属于阿里云开发者社区所有,任何媒体、网站或个人未经阿里云开发者社区协议授权不得转载、链接、转贴或以其他方式复制发布/发表。申请授权请邮件developerteam@list.alibaba-inc.com,已获得阿里云开发者社区协议授权的媒体、网站,在转载使用时必须注明"稿件来源:阿里云开发者社区,原文作者姓名",违者本社区将依法追究责任。 如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

欲瘦其包,必先探清其底细相关推荐

  1. 【视频课】深度学习入门必修,子欲学算法,必先搞数据!

    前言 欢迎大家关注有三AI的视频课程系列,我们的视频课程系列共分为5层境界,内容和学习路线图如下: 第1层:掌握学习算法必要的预备知识,包括Python编程,深度学习基础,数据使用,框架使用. 第2层 ...

  2. Maven常用插件介绍及如何打一个瘦jar包

    目录 零:说在前面 一:常用插件的介绍 二:常用插件的对比 三:打一个瘦jar包 3.1:背景 3.2:解决方案 四:插件应用举例 4.1:maven-jar-plugin 举例及部分说明 4.2:m ...

  3. SpringCloud 多模块部署瘦身包整理流程

    背景 SpringCloud 的微服务架构的应用程序发布时,多个模块可能会统一部署在一台主机上,那么就面临引用依赖过多,部署包介质过大,占用磁盘空间过多,下载耗时.更新麻烦等问题. 连续对两个项目进行 ...

  4. 半年总结——欲戴王冠,必承其重

    [Introduction] 每个女生都梦想着作为一个女王,可是你只看到了女王头上金闪闪的王冠,却不知道在这个王冠下,她是如何成长的!如果你想要做到有女王一样的权利,就必须要承担一个女王应该做到的事情 ...

  5. 2020个人年度总结:跌跌撞撞,沉下心来,不卑不燥,欲戴王冠,必承其重;

    走在互联网开发的边缘,不得不抽出时间鞭策自己学习新知识,未知的知识是 充满好奇的, 就好像一开始无线电灯成功的感觉,是那么充满信心和自豪: 但,随着时间的推移和职业的技术成长,慢慢地,这份奋斗的心不再 ...

  6. 9月心得感悟(欲戴王冠,必承其重。忙着成长,变得坚强)

    开学已经20来天了,这20来天里,经历了很多.开学第一周补完线上没办法上的物理实验,每天两三篇实验报告,闲暇时间在宿舍聊天或者复习线上没考的高数下和线代.总的来说还算可以,没有什么大事,就是复习实在不 ...

  7. JDK14+JAVAFX14+Maven定制jre打包瘦身,必成版

    注: 本教程jdk9以上版本通用(任何java项目都可以通过本教程精简jre) 博客来由: jdk9以后代码模块化逐渐成为趋势,jlink工具开始出现在人们的视野中,它可以用来定制项目所需要的jre, ...

  8. uni-app葵花宝典(欲练此功,必先自宫)

    uni-app介绍 uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等 ...

  9. 欲了解Android Studio,必先知道Gradle

    http://www.jcodecraeer.com/a/anzhuokaifa/Android_Studio/2015/0126/2361.html 泡在网上的日子 发表于 2015-01-26 1 ...

最新文章

  1. 工作中用到的java反射机制_(转)JAVA-反射机制的使用
  2. 【数据处理】python数据清洗通用手法:缺失值处理
  3. boost::intrusive::member_value_traits用法的测试程序
  4. 042、用volume container 共享数据 (2019-03-05 周二)
  5. [新品发布]全球首个百万IOPS云盘来了 阿里云推出超高性能云盘ESSD
  6. ios 系统提示框_ios13终于能屏蔽系统更新了!附详细教程
  7. 大学计算机基础总结,大学计算机基础第二章总结
  8. php异步通知并查询,服务器异步通知的接收by php
  9. 南阳理工ACM 2括号配对问题
  10. python怎么读xlsx_python读取xlsx的方法
  11. Git 核心概念:工作区与暂缓区(添加提交及查看状态充分体现)
  12. java超大数整除7,Java编写程序:求1-100之间可以被7整除的数的个数,并输出这些数。求大佬...
  13. css使背景图片旋转
  14. The tomcat server configuration at /sever/tomcat v9.0 localhost-config is.......错误解析
  15. 硬盘IDE、SATA、AHCI模式的区别
  16. 计算机c盘一直减小咋办,C盘空间越来越小怎么办有效解决方案
  17. Python JPG图片转DCM
  18. getservbyname、getservbyport
  19. 计算机新课标学习心得体会,【精品】新课标学习心得体会模板锦集10篇
  20. docker images 命令详解

热门文章

  1. 分享3 个Python冷知识
  2. zookeeper中展示所有节点_Zookeeper数据结构与监听机制
  3. dbscan算法_DBSCAN聚类算法探索
  4. php 不识别redis,redis,_redis卡死无法读取数据如何解决?,redis - phpStudy
  5. python函数手册_python学习手册——内置函数(上)
  6. 机器学习实战-SVM算法-27
  7. Linux学习笔记(3)linux服务管理与启停
  8. js条件语句初步练习
  9. Selenium | 网上教程
  10. 使用vi/vim编辑时按ctrl-s后客户端假死解决方法