背景
随着业务的发展,小程序的代码量也在迅速膨胀。 谷明最大的B端小程序页面已超过260+,dev模式下的dist目录近35M,性能稍差的设备从『代码变更-太郎热更新-小程序IDE-页面』这个过程需要更多超过13秒;而日常需求开发中,这个过程每天可能会重复数百次,这会大大降低开发效率。
构建现状分析
先说业务场景。 我们的B端小程序都是在钉钉小程序中运行的。 小程序的运行时为Taro+,工具为支付宝小程序开发者工具(以下简称IDE)。 先标记一下比较方便。 面对它并发射你的终极招式。
使用过小程序多端框架的朋友应该知道,框架层通常会构建一次,将运行时代码编译成对应平台的DSL并输出dist包,然后对应平台进行完整构建发行包。 ,最后输出离线包。
如果是模式IDE,也会全面监控dist文件。 每次更改文件时,都会重复该过程。
目前我们的技术栈首先是由Taro构建的,对应下图左侧的日志; 然后再次构建IDE,下图模拟器下的编译就是IDE构建标志; IDE构建完成后,模拟器会自动加载最新代码:
以上就是一个小程序热更新的完整流程。 看起来速度很快,没有什么问题吧? 我们增加剂量吧。
太郎身材很好
刚才我们在做一个真实的项目(页面已脱敏)。 测试设备是M1 Pro。 我们只改变了一行代码。 我们连续跑了三遍,取了最快的那一个。 您可以看到它运行了多少秒。 整个过程持续了10s+。 有的同学用的是公司提供的设备,速度就更慢了。 忽略动画中的IDE版本号,后面会有很大用处。
从两张对比图我们可以直观地看到,热更新的时间主要占用了下半年IDE的建设。 从数据来看确实如此。 Taro 的构建时间从 0.3s+ 提升到了 1.6s+,IDE 的构建速度实际上也从 2s 左右提升到了恐怖的 9s 以上。 太可怕了...
Taro 3.5之前的版本还停留在老版本,各种缓存设置没有优化,热更新还是有点慢。 恰好Taro前段时间刚刚完成升级,从3.4.0升级到3.6.19。 升级后,首次构建和热更新速度均得到大幅提升。 默认配置下200+页面的小程序热更新时间控制在2秒以内,这对我们来说已经足够了! 所以这部分Taro构建可以直接通过。
至于Taro 3.5+增加了哪些黑科技,可以移步到Taro v3.5正式版:开发体验提升。 听说后续4.0版本还支持Vite构建(很好奇它是如何支持原生esm的)。 也建议大家使用Taro版本至少3.5+。 除了构建速度提升之外,阿里巴巴小程序的包大小也将大幅减小。 ,注意是阿里巴巴系统,因为模板支持语法,每个模板会减少10k。 页数越多,效果越明显。 这里我就不详细说了。
但请注意,升级仍存在一定风险。 巧的是,我们有一个升级和陷阱的记录,仅供参考。
IDE 构建成为瓶颈
那么为什么 IDE 构建部分这么慢呢?
增加代码大小
最直观的因素就是代码量的增加。 几乎所有构建工具的构建速度都与代码量正相关。 前面提到过,IDE会再次完整构建Taro输出的dist文件夹:
下图是当前真实项目在dev模式下的dist目录。 经过几轮构建配置优化,保持在35M左右:
前后台代码的大小扩大了十几倍,因此IDE构建速度比demo项目慢是不可避免的。 即使不构建Taro,直接在IDE中修改代码,然后触发热更新,最终的结果也是一样慢。
我想有些朋友会说“这不公平”。 这是一个太郎应用程序。 七转八转都是模板代码。 如果是纯原生小程序,绝对不会是这样! ! ! 嗯~我想这样可能会好一些。 我没有验证过(没有这么大的原生小程序项目),但我想结论应该是差不多的。如果有人能验证一下,原生支付宝小程序的构建速度不会随着代码的增加而变慢,那么我会在评论区赠送10杯古茶。
IDE版本彩蛋
继上一篇友好讨论文章之后,让我们向支付宝小程序开发工具(IDE)致敬
重点来了,前方高能! ! ! 所见皆是有缘人。 请将支付宝小程序开发工具(IDE)降级至3.4.3。 我保证你的构建速度会提高30%以上。 降级后,大家一致认为它确实可以在 Mac 上运行。 如果不行的话,我再给你送5杯古茶。 如果有效,记得回来领取一键三合一奖励。
没有照片也没有证据,先拍张照片吧。 降级后,同样的代码,同样的改动,同样的IDE配置只用了4秒,太神奇了! ! ! 这篇文章不用写了,哈哈,就写完吧。 这也解释了为什么我在动画上添加IDE版本号。
至于为什么不知道,我进行了人肉测试,我记得有一天下午我偶然发现了新大陆。 有官员希望能解答我的疑惑。 你做了哪些“优化”?
3.4.3之后,官方发布了很多新版本,甚至还有比赛专用版本(好评真是好又详细,比钉钉小程序文档好多了)。 新版本增加了很多功能,修复了很多缺陷。 不管地堡里的其他功能,只是优化构建速度太快,反正我是不会升级的。
可能的解决方案
如果现在的情况是这样的话,我们来分析一下,看看有哪些可行的解决方案。
方案一:将一个小程序拆分成多个
如果单个小程序代码量太大,可以按照业务领域进行拆分,从源头减少代码量。 比如数据市场、产品管理等关联性不强、逻辑非常复杂的业务,可以拆分成两个独立的小项目。 这样,代码量就被打散了,构建速度自然就解决了。 这个方案目前还存在一些阻力,但确实是我们后续迭代B端小程序的一个大方向。
从发展的角度来看,这个方案是非常合理的。 小程序要“小”、“快”、“轻”; 小程序越小,启动体验和内存占用就越好,而且小程序的架构层也适合在发布、预览等阶段对包大小有相应的限制。 但从业务角度来看,尤其是如果操作交互在修改之前就已经固化,这会大大增加用户的学习成本。
如果要进行快速拆分,前提是应用的底层基础设施必须非常健壮,基础组件、工具库、uuc等通用能力对于每个小程序来说不能是多余的。 此外,应用之间的通信、业务拆解整理、版本管理以及后期的维护成本都是需要考虑的问题。
选项2:编译成h5
既然IDE热更新慢,我们就不能跳出来吗? 浏览器不是很好吗?
是的,确实有可能。 别忘了,古明所有的小程序都是在Taro中运行的。 Taro 的多终端功能可以自然地将代码转换为 Web 应用程序。 这样确实可以顺利进行。 只是简单的预览是没有问题的,但是实际运用到开发中还是存在一些小问题。
API差异
浏览器和IDE之间对某些API的预览模拟存在较大差异,并且由于一些兼容性问题,浏览器可以支持的API较少。 如果开发过程中需要调试,还是需要切换到IDE。
设计修复
还原设计稿时,浏览器和IDE之间始终存在差距,无法准确实现像素级还原。 因为自己打造的产品不一样,包括其他一些兼容性问题。
流程问题
想象一下,开发时前端是基于浏览器的,测试和最终上线时以小程序容器为标准。 谁知道会有多少陷阱。 开发好了,各种事情都可以在IDE里完成。 问题,你一定知道小程序容器是各种定制的黑盒子。 目前如果我们只使用小程序环境,IDE与真机之间都会存在各种兼容性问题,更不用说浏览器到真机小程序了。 因此,我认为从流程和维护成本的角度来看,我们还是应该使用小程序环境。 为准。
现在我们也在使用将Taro转换为Web的场景,但仍然仅限于文档中的演示预览和基础组件的开发预览。
选项 3:动态构造
可以“增量”建设吗? 例如,在初始化期间仅构建了页面的一部分。 当页面被访问时,动态分析页面的依赖关系,然后构建。 始终只构建所需的内容。
IDE肯定做不到。 它是一个接收 Taro 输出的 dist。 它的构建和输出一样多。 想要实施的话,就只能在太郎这边想办法了。
然后减少Taro端构建的代码。 这不仅会降低IDE的构建速度,还会降低Taro的构建速度。
其实我们之前也是这么做的,不过是手动挡。 在此之前,我们先简单了解一下Taro的构建流程:
app..js是小程序的配置文件,其中包含路由信息。 Taro 会遍历这个路由配置,并将其一一推送到监控队列中。 监控文件修改后,每次代码发生变化,Taro 都会重新构建并生成一个新文件。 区。 而这个配置文件(app..js)也会被推送到 Taro 的构建监听队列中,这意味着如果你动态修改这个配置文件(app..js),Taro 会重新走一遍整个过程。
那么前面的手动阻塞操作就是手动注释掉这个配置表(app..js)中一些目前不需要的路由,只保留本次开发需要的路由。 这样,Taro 只构建发布的路由,生成的 dist 文件就小很多,IDE 的构建压力也会相对小一些。 然而,手动操作除了繁琐之外,也会带来很多问题,比如注释错误,或者提交注释,或者需要跳转到注释的路由时需要重新构建。
所以这条路绝对是可行的。 核心问题是如何将其变成自动变速器并按需动态构建。
考虑单页应用程序 (SPA)
我们先从小程序的角度开始。 如果是传统的Web单页应用,如何提高热更新的速度呢?
少监控,各种懒加载……少编译,各种缓存,esm,umd,cdn……等等
回到小程序IDE场景,如果不考虑构建相关的优化(构建相关的优化已经被IDE收敛了),我们只能从少监控开始。
终于意识到
我们来看看最终解决方案中自动变速箱的整个流程:
核心关键步骤如下:
劫持app..js
在 Taro 中构建时,会生成一个临时配置文件 temp.app..js,仅保留最基本的路由信息(登录和登陆页面),其他配置保持与 app..js 一致。
并将Taro的app..js的引用点替换为temp.app..js,这样可以保证项目初始化并构建到最小大小。
启动本地服务管理临时配置
Taro完成后启动本地节点服务,专门用于临时配置(temp.app..js)上的CRUD。