7月QCon广州站2022,关注Web 3.0、数据架构选型、数字化转型等热门话题,点击了解 了解详情
写点什么

滴滴开源小程序框架 Mpx,致力于提高小程序开发体验

  • 2019 年 9 月 16 日
  • 本文字数:3095 字

    阅读完需:约 10 分钟

滴滴开源小程序框架Mpx,致力于提高小程序开发体验


Mpx 是一款致力于提高小程序开发体验的增强型小程序框架,通过 Mpx,我们能够以最先进的 web 开发体验(Vue + Webpack)来开发生产性能深度优化的小程序,Mpx 具有以下一些优秀特性:


  • 数据响应特性(watch/computed)

  • 增强的模板语法(动态组件/样式绑定/类名绑定/内联事件函数/双向绑定等)

  • 深度性能优化(原生自定义组件/基于依赖收集和数据变化的 setData)

  • Webpack 编译(npm/循环依赖/Babel/ESLint/css 预编译/代码优化等)

  • 单文件组件开发

  • 状态管理(Vuex 规范/多实例/可合并)

  • 跨团队合作(packages)

  • 逻辑复用能力(mixins)

  • 脚手架支持

  • 小程序自身规范的完全支持

  • 支付宝小程序的支持


设计思路

目前业界主流的小程序框架主要有 WePY,mpvue 和 Taro,这三者都是将其他的语法规范转译为小程序语法规范,我们称其为转译型框架。不同于上述三者,Mpx 是一款基于小程序语法规范的增强型框架,我们使用 Vue 中优秀的语法特性增强了小程序,而不是让用户直接使用 vue 语法来开发小程序,之所以采用这种设计主要是基于如下考虑:


  • 转译型框架无法支持源框架的所有语法特性(如 Vue 模板中的动态特性或 React 中动态生成的 jsx),用户在使用源框架语法进行开发时可能会遇到不可预期的错误,具有不确定性

  • 小程序本身的技术规范在不断地更新进步,许多新的技术规范在转译型框架中无法支持或需要很高的支持成本,而对于增强型框架来说只要新的技术规范不与增强特性冲突,就能够直接支持


技术实现

小程序刚推出时不支持自定义组件,无法进行组件化开发,WePY 和 mpvue 做了一系列的工作来支持了这一关键特性,大大提高了用户的开发体验和效率。WePY 和 mpvue 的组件化支持是基于编译做的组件化封装,用户编写的组件模板会被编译为 Page 中模板的一部分,在组件中定义的数据会被编译为 Page 中的数据,对组件进行数据更新也会基于路径映射调用 Page.setData。这在当时的技术条件下是很棒的技术方案,但该方案在复杂的小程序应用中存在性能问题,原因在于该方案中页面的数据量会很大,而且每个组件的局部更新实际上都会成为页面级别的全局更新,在组件较多的页面中产生很大的性能开销。


在小程序自定义组件推出后,我们通过性能测试确认了小程序自定义组件支持组件级别的局部更新,具有良好的更新性能。由于自定义组件在当时是最新的技术标准,业内的小程序框架都未支持,而我们在业务上又有复杂小程序的开发需求,于是我们就基于小程序自定义组件启动了 Mpx 框架的设计与开发。


Page 与 Component setData 性能对照



数据响应与性能优化

数据响应作为 Vue 最核心的特性,在我们的日常开发中被大量使用,能够极大地提高前端开发体验和效率,我们在框架设计初期最早考虑的就是如何将数据响应特性加入到小程序开发中。在数据响应的实现上,我们引入了 MobX,一个实现了纯粹数据响应能力的知名开源项目。借助 MobX 和 mixins,我们在小程序组件创建初期建立了一个响应式数据管理系统,该系统观察着小程序组件中的所有数据(data/props/computed)并基于数据的变更驱动视图的渲染(setData)及用户注册的 watch 回调,实现了 Vue 中的数据响应编程体验。与此同时,我们基于 MobX 封装实现了一个 Vuex 规范的数据管理 store,能够方便地注入组件进行全局数据管理。为了提高跨团队开发的体验,我们对 store 添加了多实例可合并的特性,不同团队维护自己的 store,在需要时能够合并他人或者公共的 store 生成新的 store 实例,我们认为这是一种比 Vuex 中 modules 更加灵活便捷的跨团队数据管理模式


作为一个接管了小程序 setData 的数据响应开发框架,我们高度重视 Mpx 的渲染性能,通过小程序官方文档中提到的性能优化建议可以得知,setData 对于小程序性能来说是重中之重,setData 优化的方向主要有两个:


1.尽可能减少 setData 调用的频次


2.尽可能减少单次 setData 传输的数据


为了实现以上两个优化方向,我们做了以下几项工作:


  • 将组件的静态模板编译为可执行的 render 函数,通过 render 函数收集模板数据依赖,只有当 render 函数中的依赖数据发生变化时才会触发小程序组件的 setData,同时通过一个异步队列确保一个 tick 中最多只会进行一次 setData,这个机制和 Vue 中的 render 机制非常类似,大大降低了 setData 的调用频次;

  • 将模板编译 render 函数的过程中,我们还记录输出了模板中使用的数据路径,在每次需要 setData 时会根据这些数据路径与上一次的数据进行 diff,仅将发生变化的数据通过数据路径的方式进行 setData,这样确保了每次 setData 传输的数据量最低,同时避免了不必要的 setData 操作,进一步降低了 setData 的频次。基于以上优化,我们大大减少了小程序 setData 的调用频次和传递数据量,与初版 Mpx 中 track 全量数据的方案相比提示显著。


Mpx setData 优化效果



Mpx 数据响应机制流程示意图


编译构建

我们希望使用目前设计最强大、生态最完善的编译构建工具 Webpack 来实现小程序的编译构建,让用户得到 web 开发中先进强大的工程化开发体验。使用过 Webpack 的同学都知道,通常来说 Webpack 都是将项目中使用到的一系列碎片化模块打包为一个或几个 bundle,而小程序所需要的文件结构是非常离散化的,如何调解这两者的矛盾成为了我们最大的难题。一种非常直观简单的思路在于遍历整个 src 目录,将其中的每一个.mpx 文件都作为一个 entry 加入到 Webpack 中进行处理,这样做的问题主要有两个:


1.src 目录中用不到的.mpx 文件也会被编译输出,最终也会被小程序打包进项目包中,无意义地增加了包体积;


2.对于 node_modules 下的.mpx 文件,我们不认为遍历 node_modules 是一个好的选择。


最终我们采用了一种基于依赖分析和动态添加 entry 的方式来进行实现,用户在 Webpack 配置中只需要配置一个入口文件 app.mpx,loader 在解析到 json 时会解析 json 中 pages 域和 usingComponents 域中声明的路径,通过动态添加 entry 的方式将这些文件添加到 Webpack 的构建系统当中(注意这里是添加 entry 而不是添加依赖,因为只有 entry 能生成独立的文件,满足小程序的离散化文件结构),并递归执行这个过程,直到整个项目中所有用到的.mpx 文件都加入进来,在输出前,我们借助了 CommonsChunkPlugin/SplitChunksPlugin 的能力将复用的模块抽取到一个外部的 bundle 中,确保最终生成的包中不包含重复模块。我们提供了一个 Webpack 插件和一个.mpx 文件对应的 loader 来实现上述操作,用户只需要将其添加到 Webpack 配置中就可以以打包 web 项目的方式正常打包小程序,没有任何的前置和后置操作,支持 Webpack 本身的完整生态。



Mpx 编译构建机制流程示意图


现状和未来

目前 Mpx 框架已经在滴滴内部大量使用,支撑了滴滴出行、青桔单车、街兔电单车、营销、车服等业务在小程序上的实现,线上运行稳定,收到了大量的好评反馈。未来我们在对框架进行持续迭代优化的同时会持续跟进微信和支付宝最新的技术标准,同时也会将在更多的小程序平台上进行适配。由于我们的设计初衷和专注点在于增强小程序开发体验,Mpx 并没有进行跨 H5 甚至是跨 Native 的支持,但现实业务当中确实存在这样的诉求,未来我们会在 Mpx 的基础上对跨端进行一定的尝试,与此同时我们依然会持续维护升级 Mpx,原因在于跨端意味着灵活性受限及能力的缺失,我们希望能给用户提供第二种选择。


Mpx 与业内主流小程序框架异同对比



结语

如果你注重开发体验和产品性能,专注于小程序开发,那 Mpx 会是一个很好的选择。最后感谢开源社区源源不断涌现出的优秀项目,给我们提供了无限的启发和巨大的技术帮助。


本文转载自公众号滴滴技术(ID:didi_tech)。


原文链接:


https://mp.weixin.qq.com/s/ybDCqZStmgcpC71f6iMHhA


2019 年 9 月 16 日 17:07772
用户头像

发布了 52 篇内容, 共 12.4 次阅读, 收获喜欢 165 次。

关注

评论

发布
暂无评论
发现更多内容

3月月更中奖名单新鲜出炉!快来看有没有你呀!

InfoQ写作社区官方

3月月更 热门活动

博睿数据首批加入云科通明湖生态联盟,赋能信创生态谋未来

博睿数据

接口自动化的关键思路和解决方案,本文全讲清楚了

Liam

Jmeter Postman API 测试工具 接口自动化测试

一文让你彻底了解Linux内核源码组织结构【建议小白收藏】

Linux爱好者

Linux内核 进程管理 驱动开发 嵌入式开发 设备驱动

EMQ 映云科技为抗疫项目提供全托管 MQTT 云服务免费使用

EMQ映云科技

物联网 IoT mqtt emq 抗疫

政企上云网络适配复杂,看华为云Stack有妙招

华为云开发者联盟

数据中心 云网络 华为云Stack 政企上云 L3GW服务

在APICloud开发平台使用友盟统计功能教程

APICloud

APP开发 APICloud 友盟

如何以卫语句取代嵌套条件表达式

华为云开发者联盟

条件表达式 卫语句 嵌套条件表达式 代码结构

PLG公司的机遇和挑战

LigaAI

SaaS LigaAI PLG

无需编程,基于甲骨文oracle数据库零代码生成CRUD增删改查RESTful API接口

crudapi

oracle 零代码 API crud 增删改查

中国设计师品牌Le Arome乐欧幕靠什么做到爆款10分钟售罄?

科技大数据

机器人流程自动化评估体系全面助力垂直行业智能化转型

王吉伟频道

RPA 机器人流程自动化 信通院

后端开发【一大波干货知识】定时器方案红黑树,时间轮,最小堆

Linux服务器开发

定时器 后端开发 红黑树 时间轮 Linux服务器开发

HertzBeat入GVP啦,并 v1.0.beta.7 发布,易用友好的云监控系统

TanCloud探云

开源 APM angular java;

ajax跨域session丢失问题

小谷哥

ajax

想减少代码量,快设置一个有感知的 Aware Spring Bean

华为云开发者联盟

spring bean Aware 接口

龙蜥开发者说:学无止境的 Linux ,以及我的第一个定制版本发布之路 | 第4期

OpenAnolis小助手

Linux 龙蜥社区 开发者说 宝贵经历

中国SaaS的增长真相|ToB大师课

ToB行业头条

《数字经济全景白皮书》Z世代用户洞察篇(1)重磅发布!

易观分析

Z世代

传统链游的革新,PlatoFarm用实际行动回馈Dao社区

西柚子

足不出户,搞定交付——独家交付秘籍(第二回)

阿里巴巴云原生

Module Federation在客服工单业务中的最佳实践

得物技术

前端 Module 模块 iframe Federation

京东运动露营活动亮相首钢园,精彩持续整个四月

科技新消息

智能化时代的数据集成技术革新

Apache SeaTunnel

大数据 开源 数据同步 Meetup Apache SeaTunnel

领域驱动设计(DDD)靠谱么?

架构精进之路

DDD 4月日更 4月月更

软件开发中的风险如何处理?

源字节1号

微信小程序 软件开发

预约中,2022京东云产业融合新品发布会线上开启

京东科技开发者

云计算 京东云 产品发布会 直播预约

滴滴开源小程序框架Mpx,致力于提高小程序开发体验_文化 & 方法_滴滴技术_InfoQ精选文章