只需几个简单的步骤即可将React Native应用程序大小减少60%

我在Mutual工作她在巴西的平等信用领域工作。我们帮助借款人和贷方建立联系。前者寻求好的赌注,而后者寻求的收益超过了市场所能提供的。我们的产品被广泛的用户使用,我们在一个很大的国家工作。结果,我们基于React Native的iOS和Android应用程序下载到了完全不同的设备上。



应当指出,我们的大部分用户都在预算设备上安装应用程序。我们可以使用来自Facebook 设备年级库的数据得出这样的结论。该图书馆在收到有关设备型号的信息后,报告了该设备在哪一年将被视为高端旗舰手机。例如,在我们的用户中最受欢迎的手机是三星Galaxy A10。尽管这款手机于2019年发布,但仅在2013年才被视为旗舰产品。分析用户设备上的数据,可以说这些设备中的85%仅在2015年或更早的时候才被视为高端设备。因此,我们对优化移动应用程序有特殊要求。优化的目的是使即使设备较弱的用户也可以舒适地使用我们的应用程序。


在特定年份可以被认为是旗舰产品的设备百分比

在这方面,我们密切关注了应用程序的大小。如果是Android版本,则为26.8 MB。尽管这不是一个很大的大小,但绝对超过了我们用户应用程序的中值大小。根据Google Play控制台,该数字为16.3 MB。对于费率计划有限的用户或内存容量低的用户,应用程序的大小可能是决定性因素,这迫使用户仔细选择要安装的应用程序。结果,必须卸载某些应用程序。这在相互申请的情况下尤其重要,因为借款人通过此申请每月支付分期付款。当借款人卸载我们的应用程序时,他按时还款的机会大大减少了。这直接影响使用我们平台的投资者的收益。


Mutual应用程序的大小比我们用户

应用程序的中值大得多,该应用程序的大小不仅影响卸载级别。大小也会影响应用程序设置的转换率。这是由Google Play团队撰写的一篇不错的文章。本文讨论了应用程序大小的重要性。特别是说,APK文件每增加6 MB,安装转换率就会降低1%。

他们还谈到这样一个事实,即在以预算工具为标准的发展中国家,这种影响甚至更大。即,在新兴市场中将APK文件的大小减小10 MB对应于安装转换率提高约2.5%。


在不同国家/地区以每10 Mb的速度增加安装的转换率,以减小APK文件的大小(根据Google内部数据),

我们非常有动力,因为减小应用程序的大小会如何影响卸载级别和应用程序设置的转换率。因此,我们考虑到用户的便利性,着力于尽可能减小应用程序的大小。该项目的第一步是分析Google对Android开发人员的官方建议

Android应用程式套件


阅读建议后,我们了解到减小应用程序大小的最简单方法是使用一种称为Android App Bundle(AAB)的新应用程序分发方法。在此之前,我们分发了该应用程序,收集了可以在大多数Android设备上运行的旧的Android Package(APK)文件,并将其上传到Google Play控制台。但是AAB包仅包含编译后的代码和资源。因此,在下载后,Google会负责考虑各种设备的规格和CPU架构,为各种类型的设备生成优化的APK文件。

事实证明,通过对项目的构建过程进行简单的更改,我们可以在不付出更多努力的情况下就大大减少应用程序的大小吗?这真是太好了!

阅读文档后,我们只是更改了React Native Gradle构建脚本,使其assembleRelease可以运行,而不是当前运行的脚本bundleRelease。这就是创建AAB文件所需的全部。在对Fastlanesupply配置进行了一些修改后,将素材直接自动上传到Play商店后,我们切换到了AAB,并且我们的应用程序的新版本出现在Google Play控制台中。

仅此一项更改就减少了传输到用户设备的APK文件的大小。下降幅度为9.1至12.4 Mb。事实证明,使用Android App Bundle是一种有效的技术,确实可以使您减小应用程序的大小。


旧的APK文件和新的AAB捆绑包使用它们会导致一个事实,即不同设备上的应用程序大小可能在14.4 MB到17.7 MB之间

。True,请注意此处。如果您将React Native与 Hermes一起使用,则可能需要更新您的依赖项soloader(请参阅此处的详细信息)。否则,可能会给用户提供一个包含严重错误的应用程序。我们很幸运,我们能够在测试项目的Alpha版本期间发现此问题。但是由于该错误在本地测试或构建APK文件时不会出现,因此很容易误入生产环境。

使用Android Size Analyzer优化应用程序资源


我们在文档中找到的优化应用程序的下一个建议是使用Android Size Analyzer这是一个命令行工具,可分析Android应用程序并寻找减小其大小的方法。我们使用以下格式的命令启动了此工具:

size-analyzer check-bundle [BUNDLE].aab

结果,我们获得了可优化的出色应用程序资源和映像的列表。还建议我们设置ProGuard。


尺寸分析仪报告

GuardProGuard


ProGuard是用于压缩,混淆和优化Java字节码的工具。由于我们了解到它可能与某些Android库不兼容,因此我们尚未探讨使用此工具的可能性。由于我们力求尽快缩小应用程序的大小并使之尽可能简单,因此我们决定在将来保留这种优化方法。

app大型应用程序资源


size-analyzer再次使用键 运行它-d,我们得到了一个应用程序资源列表,按资源大小排序。由于此工具对用户如何使用应用程序一无所知,因此它使我们有机会独立决定应删除哪些资源以及应将哪些资源动态加载到应用程序中。


按大小排序的大型应用程序资源

列表此列表上的第一个也是最大的资源是React Native JavaScript捆绑包。现在,我们无法拆分此捆绑包并动态加载它。但是稍后我们会考虑的。列表的下方是大字体文件(TTF)和图像文件(JPG和PNG)。

images不必要的图像


我们立即注意到了故事书中使用的巨大JPG图像我们使用该系统来开发和测试组件。这是2 MB的垃圾,属于该项目的生产版本。可耻的错误!当发生这样的事情时,我们觉得自己做了一些严重的愚蠢。但是在复杂的软件开发世界中,每个人都会犯错。我相信,如果您公开谈论自己的错误,它将帮助其他开发人员从这些错误中学习。如果不分析应用程序的资源结构,该应用程序的大小会逐渐增加,则可能会犯同样的错误。

▍字体


在我们迅速消除了不必要的图像之后,我们继续分析资源列表的其他元素。很明显,其中有很多内置字体。在与设计师讨论了这一问题之后,他们告诉我们,许多旧组件在严格遵守印刷手册方面没有不同。因此,我们发现可以删除哪些组件,以及可以在其中使用适当的更新字体。因此,我们能够将使用的字体数量从六种减少到四种。

我们注意到的另一件事是字体文件本身的大小。它们每个的大小约为670 Kb。这意味着未压缩包中的四种字体占据了惊人的2.7 Mb。但是,幸运的是,有一个名为FontForge的工具,可让您深入分析和修改字体文件。使用该工具,我们发现字体文件大的主要原因是扩展的西里尔字母和不必要的字形。我们可以安全地删除所有这些内容,因为应用程序的文本部分完全用葡萄牙语编写的。由于此更改,我们得以将字体文件的大小从670 Kb减少到70 Kb-减少了90%。


字体中包含一些标志符号的示例,

由于我们摆脱了不必要的字体并优化了其余字体,因此能够将应用程序大小减少3.8 Mb。这导致APK文件的总大小减少了2 MB。


优化之前的字体及其大小列表


优化后的字体列表及其大小

images图像优化


在分析仍然保留在应用程序中的图像之后,我们注意到其中一些图像非常大。我们使用TinyPNG图形优化工具处理了其中的几幅图像,并发现这些图像的大小已大大减少。之后,我们决定优化该应用程序中使用的所有JPG和PNG图像。其中有41个。


优化前后的图像

这为我们提供了将图像大小从2.5 MB减少到756 KB的机会,即减少了70%。但是,由于图像以前没有进行过优化,因此在创建最终APK文件时将其压缩。事实证明,我们的优化使用户下载的应用程序大小仅减少了500 Kb。

之后,我们意识到我们已经用尽了所有快速优化的可能性。继续优化资源将需要付出很大的努力或仅需进行微小的改进。

响应本机JavaScript包优化


在确定了特定于Android平台的应用程序资源之后,是时候分析JavaScript包了。出于以下三个原因,可以将捆绑包优化视为一个好主意。首先,它减小了完成的APK文件的大小。其次,由于JS虚拟机必须处理更少的代码,因此可以更快地启动应用程序。最后,最重要的是,它加快了我们每周使用CodePush进行几次的OTA更新的速度

▍捆绑分析器和代码优化


为了决定如何减小捆绑包的尺寸,首先,您必须弄清楚捆绑包中占据最大位置的是什么。为此,我们使用了出色的开源工具react-native-bundle-visualizer。在项目的帮助下进行分析之后,我们得到了一个可视化视图,其中显示了每个文件夹和每个应用程序依赖项,指示了相应实体的大小。


指示大小的Mutual应用程序前端代码库的库和文件夹的快照,

我们发现捆绑包的总大小为5.49 Mb。该卷的57.8%由文件夹node_modules27.5%-应用程序代码中的依赖项表示。剩下的,我们使用的工具无法确定。在捆绑软件的组装过程中,未使用的代码已被删除,因此我们看到的是应用程序实际使用的代码。但是,即使考虑到这一点,您仍然可以在捆绑销售中找到可以改进的地方。

最大的项目依赖性是math.js。顾名思义,该库实现了许多数学运算。由于我们在服务器上执行了所有重要的计算,因此我们仅将结果发送到应用程序,因此我们对该库没有特别的需求。当我们查看应用程序代码时,发现该库仅用于执行一些简单的操作。最有可能是由习惯于开发服务器代码的开发人员使用的。我们从库中快速提取了适当的方法,并将其构建到我们的代码库中,完全摆脱了这种依赖。这样可以将捆绑包的大小减小到4.64 Mb。拒绝仅使用一个库就可以将捆绑包的大小减少15.5%!

如前所述,我们使用Storybook来开发和测试组件。的确,相应的功能应仅在本地和中间环境中可用。最终用户不需要此。由于这一点,我们使用了该变量ENVIRONMENT来控制应用程序相应部分的包含。尽管这适合限制访问,但是捆绑程序无法知道将什么值写入此变量。由于此限制,所有Storybook代码都落入了产品包中。

为了解决该问题,我们在单个文件中隔离了此部分的导入。然后,我们创建了此文件的两个版本:一个包含Storybook,另一个用于生产,仅包含组件布局。为了在准备捆绑产品的生产版本时在这些文件之间切换,我们编写了一个脚本,该脚本在构建项目之前执行,并将一个文件更改为另一个文件。借助这种方法,我们能够从应用程序的生产版本中完全删除Storybook代码,从而消除了与node_modulesStorybook“故事”配置有关的依赖和常规代码。


使用两个版本的索引文件更新了Storybook文件夹,

这两项更改将捆绑包的大小从5.49 MB减小到4.2 MB。这意味着,除其他外,应用程序将更快地加载和更新。


最终捆绑包的大小为4.2 MB,

经过所有这些改进,我们再次在Play商店中下载了该应用程序。现在我们被告知完成的APK文件的大小将在10.5到13.7 Mb的范围内。考虑到该应用程序最初的大小为26.8 MB,这仅意味着该项目的大小就惊人地减少了约60%!因此,正如我们在Google Play小组的一篇文章中所说,我们完全可以预期安装的转化率将提高3.75%。


将应用程序的原始APK版本与最终的AAB版本进行比较,其中进行了上述所有改进

摘要


作为面向业务的程序员,我们知道有时公司为了项目的更快开发而可能会继续增加其技术债务。对于像Mutual这样的年轻初创公司来说尤其如此,他们试图在市场上找到自己的位置。但是,如果您没有注意到这笔债务,则可能会犯下令人讨厌的错误,例如将2 MB的测试图像发送到生产环境,以及不合理地使用庞大的库。不应让技术债务失控并造成麻烦。

另外,经常发生的情况是,开发人员只是错过了可用于优化项目的机会。因此,有时建议您严格分析您的项目。只是检查您是否错过了快速优化应用程序的大小,速度或其他方面的机会。我们只花了两天时间就分析了应用程序,计划了工作并对项目进行了改进,这使我们将应用程序的大小减少了60%。在这么短的时间内很难想出其他可以产生相同结果的东西。

您如何优化React Native项目?


All Articles