网站推广.NET

网站推广.NET

Didi Chuxing小程序体积优化实践

来源:互联网

概述

2019年下半年,为了将微信钱包/支付宝九宫格入口处的滴滴出行迁移到小程序,该团队进行了许多功能升级和补充小程序。在整个过程中也遇到并克服了一系列问题和挑战,其中包装体积的问题尤为突出。接下来,我将全面介绍滴滴出行小程序在音量控制方面的努力和沉淀。

背景

微信对小程序包装的体积的要求是总体积不得超过12M,主包装和单个子包装的体积不得超过2M。尽管支付宝对小程序的包装量的计算方法与微信的包装量略有不同,但总体包装是相似的。

从18到19年初,滴滴出行小程序仅提供在线汽车叫车服务,并且业务需求较少,可以在主程序包中完成。下半年,为了将微信钱包/支付宝九宫格入口迁移到小程序,小程序开始增加许多业务类别,例如公交车/司机/汽车服务/自行车/顺风汽车,以及在线汽车叫车还必须充分满足业务需求,并且业务量和代码量一起增长。

Didi Travel包括丰富多样的旅游业务,包括特快/特殊汽车/出租车/豪华汽车/拼车/自行车/按需汽车/搭便车/公共汽车/汽车生活以及许多其他业务。整个Didi Travel小程序中最重要和最常用的页面是主页和订单详细信息页面。主页载有每个业务线的需求表达,每个业务线的订单详细信息页面载有特定的旅行订单显示。逻辑。此外,还有各种功能页面,例如个人中心,营销页面,设置,历史行程。

根据Didi Travel的产品逻辑,所有业务线的需求表达逻辑都显示在主页上。为了获得良好的切换体验,首页上使用了单页顶部指南来显示业务线。也就是说,每个业务线在首页上都提供了一个需求表达组件,并且当用户切换顶部指南业务线时,相应的业务线组件也会被切换。

在这种设计下,表达所有业务线需求的逻辑集中在主页的单个页面上,这导致在业务迭代过程中承载主页的主程序包的数量迅速增加,快速接触小程序平台的单包2M上限对后续业务迭代和开发构成了巨大障碍。因此,控制包装体积是我们在开发小程序时遇到的一个大问题。

音量控制

下面,我们将在Didi Travel小程序的开发迭代过程中针对小程序包装量介绍一系列优化控制方法。

基本优化方法

对于小程序,基本的软件包大小优化方法包括:资源压缩/代码冗余删除/资源CDN /异步加载

在Web开发中,webpack提供了许多代码优化功能,包括依赖关系分析,模块重复数据删除,代码压缩,树抖动,副作用等。这些功能可以轻松完成资源压缩并消除代码冗余。 。 Didi Travel小程序是基于Didi的开源小程序框架Mpx(/ didi / mpx)开发的。 Mpx框架的编译和构建完全基于webpack,并且与webpack的内部生态兼容。当然,以上功能可用于优化包装体积。

小程序支持使用CDN地址加载某些静态资源(例如图像和视频)。我们将压缩相关资源,并尽可能将它们放在CDN上,以避免这些资源占用包裹量。

在小程序场景中,无法通过Web中的脚本标签方便地进行异步加载,但是小程序平台后来支持子包加载方案以实现此功能,因为子包加载对于小程序 webpack无法直接支持技术规范。因此,Mpx框架专门为此技术规范提供了良好的适应性支持。稍后我们将详细介绍此功能的应用。

此外,Mpx框架还针对小程序场景进行了很多程序包量优化调整工作,例如减少了框架在运行时(压缩后为56Kb)所占用的程序包量,以及所引用的页面/组件按需打包和构造,声明公共样式以供样式重用,并提取分包中的通用模块。

借助Mpx框架的这些功能,无需额外配置即可构建经过初步优化的小程序软件包。

微信也可以在开发人员工具选项中检查类似的“上载代码时自动压缩和混乱”,但是在开发人员工具中上载代码时的计算量直接是当前项目代码的量计算得出的,并且不会基于压缩量。因此,如果您使用本机小程序进行开发,则很可能会进一步压缩源代码以节省空间。

分析量

尽管该框架在音量控制方面提供了许多优化,但我们发现随着业务的不断发展,主程序包仍然太大。

遇到大尺寸主包装后,我们需要弄清楚主包装中有什么?他们为什么这么大?

使用本机小程序或其他非基于Webpack的框架进行开发的学生可能在遇到此问题后必须查看硬盘上的文件大小。结果,每个模块的大小可能不直观。我们可以使用webpack插件(如webpack-bundle-analyzer)进行辅助分析。

例如,这是一个使用Mpx框架编写的演示。您可以通过npm run build --report:

看到这样的界面

您可以看到此演示项目由第三方库组成,例如moment / lodash / socket-weapp / core-js。每个库的大小和相互依赖性也可以清楚地看到。

对于Didi Travel小程序,您可以看到类似的图片,并且可以看到整个项目由什么代码组成。

此外,Didi Travel的前端开发始终采用“源代码编译”,该代码只允许共享整个项目中公共依赖项的一个副本。简而言之,它还有助于减小项目代码的大小。相关信息:

要充分发挥源代码编译的作用,上游和下游必须构建完整的源代码编译生态系统。例如,当主项目的依赖方声明公共依赖项时,他们应使用peerDep或devDep声明一些公共依赖项。这些共享的依赖项应该在主项目中的“做一个统一的声明”中,以避免由于版本不同而安装两个公共依赖项,这会增加大小。由于Didi Chuxing小程序涉及大量业务线和团队,因此某些团队可能不知道这一点,因此上述降级方案实际上可能会出现在代码中。根据分析图,可以轻松发现此类问题,并推动相关团队消除这些重复的依赖关系。

同时,根据卷分析图,我们着重于对较大文件的分析,进行了一轮业务代码排序和精简,删除了一些无用的代码,精简了websocket消息主体描述文件,等等。

配置分包

分包是小程序提供的方案,类似于网络的异步引入。可以将某些在初始条目中不需要的页面放入子包中,并且当相应页面跳转到该子包时,将下载该子包。将页面及其辅助资源放入子包中可以有效减小主包的大小。

在早期,Mpx框架为分包规范提供了初步支持,并且资源访问规则仍与微信保持一致。它主要基于存储资源的目录来确定是输出到主包还是分包。借助此功能,我们将行程表分包了出去,行程表可能占用了200K以上的空间。

成功分割了行程页面后,我们开始将所有非主页代码分包给客户,例如开始和结束选择以及个人中心。而且某些业务线是通过npm访问的,我们还将这些业务线的所有非主页代码都尽可能多地转包给了分包商。

这里还有另一个题外话。借助mpx打包形式的业务合并计划的早期设计,可以方便地独立开发业务,并且可以轻松地进行集成。然后,我发现微信子软件包的json配置设计与软件包非常相似,并在此基础上支持微信子软件包。用户只需要向原始软件包添加查询以标记子软件包的名称。就是这样。

在拆解每个分包合同之后,整个项目结构大致如图所示:

初步的分包工作完成后,从主包装到分包装中总共移走了400K的空间。

分包资源的精细管理

如上所述,Mpx框架的初始分包规则是按照微信的方法将分包路径下的资源完全收集到分包中。由于npm管理的资源全部在node_modules目录中,并且不属于任何子程序包路径,因此它们将全部收集到主程序包中。

例如,在进行行程单分包之前,行程单的状态管理存储都在行程单分包的路径下,并将其收集到行程单分包中。行程页面还使用封装的didi-socket库。该库是公共的npm软件包。即使仅在行程页面子包中使用它,但由于它的路径在node_modules下,因此将其收集到主包中。

由于一些早期的设计,行程页面和主页的资源是分开的,并且它们相对独立地存在于它们各自的路径中。第一阶段转包过程的主要部分也是适合Mpx的行程页面。初始分包处理的特性,因此可以在分包过程中更好地收集它。

随着业务的迭代,将通过npm进行对大量业务线的后续访问,并且将有大量的npm包资源。它们都在node_modules目录中,因此它们都将被收集到主程序包中。

因此Mpx框架经历了一系列转换:

在构建依赖项收集过程中,我们将标记收集的依赖项并记录哪些子包引入了它。一旦仅导入一个子包,它将被输出到该子包。我们将根据用户定义的子包配置自动为SplitChunksPlugin中的每个子包生成cacheGroups,并将子包中的多路复用模块提取到子包下的包中。对于组件和静态资源,如果它们被多个分包合同引用而未在主包中引用,则为确保主包的最佳数量,这些资源将生成多个副本并输出到相应的分包合同,而不是被占用主包装体积。

这样,无论子包中引用的资源最初位于何处,它们都将在最终输出中尽可能多地输出到dist的子包目录,以避免占用主包空间。

此更改完成后,项目结构与以前相同,但是由于Mpx处理分包资源的能力得到了升级,我们能够成功输出业务分包行中为其分包的业务所引用的npm资源目录。

封面计划

后来,Didi Travel小程序需要替换微信 / Alipay中的原始WebApp门户。小程序访问业务线的速度迅速增加,包裹数量迅速增加。

这部分中体积增加的主要原因已在前面提到。所有业务线都必须连接到主页才能显示。这也取决于业务的特征。滴滴出行提供了丰富的旅游产品线,包括特快车/特种车/出租车/豪华车/拼车/自行车/代理驾驶/顺风驾驶等产品。用户可能需要反复切换。 。此过程还保留诸如开始和结束模型之类的信息。它必须是页面内的切换组件,再加上一组要非常顺利地实现的非常复杂的大规模状态管理。它不像某些电子商务/信息平台将不同的功能分为不同的页面,而是允许用户通过主页上的菜单进入子页面然后执行操作。主页仅包含入口,并且具有较少的业务逻辑。这样会容易得多。

因此,每个业务线都必须提供用于访问的主页组件。该组件将在主页上使用,因此不能以任何方式打开包装。最后,整个主页的主程序包部分的卷可以分为两部分:基本库和业务代码。对于公共依赖库,两者的体积比可能约为1M,对于业务代码,两者的体积比约为1M。

如此大的基础库数量主要是由于滴滴出行的业务线和业务团队数量众多,并且各方都有一些基本的依存关系。例如,在线汽车叫车依赖的长链接通信pb数据描述文件,地图将依赖的大量计算库,顺丰车所依赖的CML框架运行时,驾驶员所依赖的通信网关库,以及公共组件库和polyfill。

因此,Didi Travel小程序面临的问题不再能够在短时间内通过纯技术解决方案快速解决该问题,因此我们进行了工程结构调整,可以将其称为封面解决方案,解决了主要包装问题。

封面计划只是简单地将Didi Travel Logo作为起始页面进行封面,一旦页面被加载,它将立即跳转到另一页。该页面实际包含业务,并放置在子包中。

此操作的重要性在于,仅将所有各方都必须依赖的基本框架/库等保留在主程序包中,并且将业务全部从分包合同中取出。

这是完成封面图后的项目结构图。主页业务逻辑的很大一部分已提取到主页子包中。

这种移位操作的结果是,我们可以拥有2M主程序包空间来复制和发布基本公共库,还有2M子程序包来复制和发布上述的Didi Travel,它集成了各种“主页”。那时,几乎有1.2M个主软件包和80万多个业务主分包合同。

此转换最突出的一点是,后续业务迭代产生的数量增长几乎完全在主业务分包中,而剩下的1.1M +空间对于业务迭代而言相对比较丰富。在理想条件下,主包装的体积可以长时间保持不变。业务需求的不断发展不会使主包装的体积反复超过标准,也不必担心主包装的体积。

当然,您可以看到该计划本身并没有减少任何数量,而只是改变了位置。此外,该封面解决方案实际上还有一些缺点。例如,第一个屏幕业务的显示将变慢,因为要加载的内容将增加,但是小程序本身具有更好的缓存资源的能力,因此仍然可以接受。

与由于数量问题导致的需求迭代和产品线访问相比,该解决方案至少可以解决问题。我们的开发团队将继续跟进并关注数量问题,以查看是否会更改产品程序,或者小程序本身提供了一些解决方案来进一步优化此部分。

摘要

Mpx框架在包装体积控制方面做了很多工作,并且为npm场景中的小程序分包提供了非常完整的支持。

在框架支持的基础上,Didi Travel小程序团队在不妨碍业务发展的情况下,整理了业务依存关系,充分利用了分包合同,并调整了互动计划等。行程小程序包裹大小受平台限制。

希望本文可以为有包装尺寸问题的小程序开发人员带来启发,请留言并进行交流。