HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

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

  • 2019-09-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-09-16 17:071194
用户头像

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

关注

评论

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

以解析csv数据为例,讨论string、char[]、stream 不同类型来源是否能进行高性能读取解析封装可能性

八苦-瞿昙

C#

亚马逊云科技为派拓网络打造数字安全平台产品组合

财见

作为程序员,沟通能力是否重要?

小齐写代码

策略分析:Atlassian Server版停止支持,Server版用户应该转向数据中心版本还是云版?

龙智—DevSecOps解决方案

区块链游戏解说:什么是 Arcade Champion

Footprint Analytics

云桌面哪家好用?

青椒云云电脑

云桌面 云桌面厂家 云桌面解决方案

教你如何用Keepalived和HAproxy配置高可用 Kubernetes 集群

华为云开发者联盟

开发 华为云 华为云开发者联盟

KaiwuDB 拿下 “物联之星” 双项殊荣

KaiwuDB

数据库 物联网

致 Tapdata 全体用户:2023 年,我们把更多精力集中到了产品能力和稳定性上

tapdata

数据库

通过解析库探究函数式抽象代价 ( ini 解析示例补充)

八苦-瞿昙

C#

活动回顾 | DevData Talks沙龙深圳站:中小到千人规模团队研发效能提升实践

思码逸研发效能

前端:Vue2.0和Vue3.0的一些入门对比

秃头小帅oi

前端 低代码 js Vue 3 vue2

开班在即 | 测试开发名企定向培养训练营,手把手带你提升核心竞争力!

测吧(北京)科技有限公司

测试

蒋安祥:巴拿马奖项评选指南与规程赢得企业界广泛认可

Geek_2d6073

蜗牛游戏宣布利用AI技术提升其开发流程

财见

鸿蒙移动开发加速器何处寻?

Geek_2305a8

SNZ资本的首席信息官Gavin确认出席Hack .Summit() 2024香港开发者大会!

TechubNews

破防了,谁懂啊家人们:记一次mysql问题排查

阿里技术

MySQL 索引 问题排查 表结构

聊聊Java 类属性与类方法的应用

伤感汤姆布利柏

Java 前端

Supermicro 通过新基础设施解决方案,加速 5G 和电信云工作负载性能

财见

追踪Jira中项目成本与工时,更符合国人使用习惯——TimeWise工时管理

龙智—DevSecOps解决方案

DevOps DevSecOps Atlassian

EMQX Enterprise 5.5 发布:新增 Elasticsearch 数据集成

EMQ映云科技

mqtt mqtt broker

通过解析库探究函数式抽象代价

八苦-瞿昙

C#

客户案例 | 思码逸DevInsight帮助企业提炼关键指标,建立研发效能体系

思码逸研发效能

手机厂商的开年大考:卷AI,还是卷MR?

Alter

MR 大模型 AI手机

PTS 3.0:开启智能化的压测瓶颈分析

阿里巴巴云原生

阿里云 云原生 压测

密码学在 Web3 钱包中的应用:私钥是什么?bitget钱包为例

威廉META

喜讯 | 思码逸Devinsight 入选中国信通院《高质量数字化转型产品及服务全景图》

思码逸研发效能

即时通讯技术文集(第34期):IM群聊技术合集(Part1) [共15篇]

JackJiang

网络编程 即时通讯 IM

Udemy 上最受欢迎的免费编程课程

秃头小帅oi

php 学习 React 课程 java

超越传统:人工智能赋能的自动化测试新前景

测吧(北京)科技有限公司

测试

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