最近半年,我们团队在做微信小程序开发,先后尝试了原生小程序、wepy、mpvue等几个主流的小程序开发框架。

小程序这两年特别火,几乎每个公司都在做小程序。但是小程序的原生开发体验,说实话,不太好。语法和传统的前端开发不一样,组件化能力弱,开发效率低,调试也不方便。所以,社区里出现了很多小程序开发框架,比如wepy、mpvue等,目的是提升小程序的开发效率和开发体验。

我们团队在选择框架的时候,纠结了很久,最后决定每个框架都试一试,看看哪个更适合我们。结果,在选择和使用框架的过程中,我们踩了很多坑,熬了很多夜,也积累了不少经验。

今天就来对比这几个主流的小程序开发框架,分享我们在使用过程中踩过的坑,希望能给正在做小程序开发的朋友一些参考和提醒。

一、为什么需要小程序框架

在开始对比之前,先说说为什么需要小程序框架,原生小程序开发有什么问题。

微信小程序的原生开发,有自己的一套语法和规范,和传统的前端开发(HTML/CSS/JS)不太一样:

  1. 模板语法不同:小程序用的是WXML,和HTML类似,但是有很多不同的地方,比如属性名、事件绑定、列表渲染、条件渲染等,都有自己的语法。
  2. 样式语法不同:小程序用的是WXSS,和CSS类似,但是支持的选择器有限,不支持通配符选择器,不支持部分CSS属性,还有rpx等小程序特有的单位。
  3. JS语法不同:小程序的JS逻辑层,有自己的一套API和生命周期,和传统的前端开发不一样。而且小程序的逻辑层和视图层是分离的,数据传递需要通过setData,有一定的性能开销。
  4. 组件化能力弱:小程序原生的组件化能力比较弱,虽然支持自定义组件,但是功能有限,使用起来也不够方便。
  5. 开发效率低:因为语法和传统前端不一样,前端开发者需要学习新的语法,开发效率比较低。而且小程序的工程化能力比较弱,不支持npm包管理(早期),不支持ES6+的所有特性,构建工具也比较弱。

因为这些问题,社区里出现了很多小程序开发框架,目的是让开发者能用熟悉的语法(比如Vue语法)来开发小程序,提升开发效率和开发体验。

目前比较主流的小程序框架有:

  • wepy:腾讯团队开源的小程序框架,语法类似Vue,支持组件化、Promise、async/await等。
  • mpvue:美团团队开源的小程序框架,基于Vue.js,开发者可以用Vue的语法开发小程序,还能复用Vue的生态。
  • 原生小程序:微信官方的开发方式,虽然体验一般,但是最稳定,兼容性最好。

下面我们就来对比这几个框架,分享我们踩过的坑。

二、原生小程序:最稳定但效率最低

先说说原生小程序。

我们最开始做小程序,用的是原生小程序开发。因为觉得官方的东西最稳定,兼容性最好,而且文档也最全。

优点

  1. 最稳定,兼容性最好:原生小程序是官方的开发方式,兼容性最好,不会因为框架的bug导致小程序出问题。微信小程序的API更新,原生小程序能第一时间支持,不需要等框架更新。
  2. 性能最好:原生小程序没有框架的额外开销,性能最好,特别是在低端手机上,性能优势更明显。
  3. 文档最全:官方文档最全,遇到问题容易找到解决方案。而且社区里原生小程序的教程和案例也最多。
  4. 没有学习成本:虽然语法和传统前端不一样,但是只要学会了,就没有额外的学习成本。而且原生小程序的语法比较简单,学起来也不难。

缺点和坑

  1. 开发效率低:这是原生小程序最大的问题。因为语法和传统前端不一样,前端开发者需要学习新的语法,开发效率比较低。而且小程序的工程化能力比较弱,代码复用性差,维护成本高。
  2. 组件化能力弱:原生小程序虽然支持自定义组件,但是功能有限,比如组件之间的通信比较麻烦,不支持高阶组件,不支持mixin等。复杂的页面,代码会很臃肿,维护起来很麻烦。
  3. setData性能问题:小程序的逻辑层和视图层是分离的,数据传递需要通过setData。如果频繁调用setData,或者一次setData的数据量太大,会导致性能问题,页面卡顿。这个问题在复杂页面上特别明显,需要特别注意。
  4. 不支持npm包管理:早期的小程序不支持npm包管理,想用第三方库,只能手动下载源码,放到项目里,很不方便。虽然后来小程序支持了npm,但是使用起来还是比较麻烦,有很多限制。
  5. 调试不方便:小程序的开发者工具,虽然功能在不断完善,但是和Chrome DevTools比起来,还是差很多。调试的时候,经常遇到断点不生效、console.log不显示、数据看不到等问题,调试体验不太好。

适合场景

原生小程序适合以下场景:

  • 小程序比较简单,页面不多,逻辑不复杂
  • 对性能要求很高,特别是低端手机的性能
  • 团队不熟悉Vue等前端框架,或者不想引入额外的框架
  • 需要第一时间支持小程序的新API和新特性

三、wepy:类Vue框架,组件化能力强

再说说wepy。

wepy是腾讯团队开源的小程序框架,应该是最早的一批小程序框架了。wepy的语法类似Vue,支持组件化、Promise、async/await、Mixin等,开发体验比原生小程序好很多。

我们第二个项目,尝试用了wepy,整体体验还不错,但是也踩了不少坑。

优点

  1. 语法类似Vue,学习成本低:wepy的语法类似Vue,比如数据绑定、事件处理、计算属性、watch、生命周期等,都和Vue很像。熟悉Vue的开发者,很快就能上手wepy,学习成本很低。
  2. 组件化能力强:wepy的组件化能力比原生小程序强很多,支持组件嵌套、组件通信、Mixin、高阶组件等,代码复用性好,维护成本低。复杂的页面,也能拆分成多个组件,代码结构清晰。
  3. 支持Promise和async/await:wepy支持Promise和async/await,异步代码写起来更简洁,可读性更好。不用再写嵌套的回调函数了,异步代码的维护成本降低了很多。
  4. 支持ES6+特性:wepy支持ES6+的特性,比如箭头函数、解构赋值、模板字符串、let/const等,开发体验更好。而且wepy有构建工具,支持代码压缩、文件监听、自动编译等,工程化能力比原生小程序强。
  5. 插件生态丰富:wepy有丰富的插件生态,比如wepy-redux、wepy-async-function等,可以很方便地集成Redux、async/await等功能。

缺点和坑

  1. 框架本身有bug:wepy虽然是腾讯团队开源的,但是框架本身还是有一些bug,特别是在一些边界情况下。我们在使用过程中,遇到过组件通信失效、数据不更新、编译错误等问题,排查起来很麻烦,因为你不知道是自己代码的问题,还是框架的问题。
  2. 性能问题:wepy在原生小程序的基础上做了一层封装,有一定的性能开销。特别是在复杂页面上,wepy的性能比原生小程序差一些,在低端手机上可能会有卡顿。而且wepy的setData做了封装,有时候会导致一些性能问题,需要特别注意。
  3. 文档不够完善:wepy的文档虽然有,但是不够完善,很多特性和API没有详细说明,遇到问题需要看源码或者在社区里找答案。而且wepy的更新速度比较慢,一些新特性和bug修复,需要等很久。
  4. 和Vue还是有差异:虽然wepy的语法类似Vue,但是和Vue还是有一些差异,比如wepy的组件通信方式、生命周期、数据绑定等,和Vue不完全一样。熟悉Vue的开发者,有时候会混淆,写出有问题的代码。
  5. 社区活跃度下降:wepy虽然是最早的小程序框架之一,但是最近社区活跃度有所下降,新版本更新慢,问题响应也慢。相比之下,mpvue等新框架的社区活跃度更高。

适合场景

wepy适合以下场景:

  • 团队熟悉Vue语法,想用类Vue的语法开发小程序
  • 小程序比较复杂,需要强组件化能力
  • 对性能要求不是特别高,特别是低端手机的性能
  • 团队有一定的框架使用经验,能排查框架层面的问题

四、mpvue:基于Vue,复用Vue生态

再说说mpvue。

mpvue是美团团队开源的小程序框架,基于Vue.js,开发者可以用Vue的语法开发小程序,还能复用Vue的生态,比如Vuex、Vue Router等。mpvue是最近比较火的小程序框架,社区活跃度很高。

我们第三个项目,尝试用了mpvue,整体体验比wepy更好,但是也踩了一些坑。

优点

  1. 真正的Vue语法,学习成本最低:mpvue是基于Vue.js的,用的是真正的Vue语法,而不是类似Vue的语法。熟悉Vue的开发者,可以几乎零学习成本上手mpvue,直接用Vue的语法开发小程序。数据绑定、事件处理、计算属性、watch、生命周期、组件通信等,都和Vue完全一样。
  2. 可以复用Vue生态:mpvue可以复用Vue的生态,比如Vuex(状态管理)、Vue Router(路由管理,mpvue有自己的适配)等。如果你已经有Vue项目,可以很方便地把Vue项目迁移到mpvue,很多代码可以直接复用。
  3. 组件化能力最强:mpvue的组件化能力是这几个框架中最强的,因为它用的是真正的Vue组件系统。支持组件嵌套、组件通信、Slot、Mixin、高阶组件、函数式组件等,组件化能力和Vue一样强。复杂的页面,也能很好地拆分成组件,代码结构清晰,复用性好。
  4. 工程化能力强:mpvue基于Vue-cli,工程化能力很强,支持webpack构建、代码压缩、热更新、ES6+、CSS预处理器等。开发体验和Vue项目几乎一样,非常舒服。
  5. 社区活跃度高:mpvue是美团团队开源的,社区活跃度很高,版本更新快,问题响应也快。而且美团自己也在用mpvue开发小程序,有实际项目验证,框架的质量有保障。

缺点和坑

  1. 框架封装层更厚,性能开销更大:mpvue在原生小程序的基础上做了更厚的封装,性能开销比wepy更大。特别是在复杂页面上,mpvue的性能比原生小程序差不少,在低端手机上可能会有明显的卡顿。而且mpvue的响应式系统,有时候会导致一些不必要的setData,影响性能。
  2. Vue和小程序的差异导致的问题:虽然mpvue用的是Vue语法,但是小程序的运行环境和浏览器不一样,有些Vue的特性在小程序里不能用,或者行为不一样。比如Vue Router不能直接用(mpvue有自己的路由方案),部分Vue插件不能用,部分CSS特性不支持等。这些差异,有时候会导致一些奇怪的问题,排查起来很麻烦。
  3. 调试更困难:mpvue的代码是编译成小程序代码运行的,调试的时候,你看到的是编译后的代码,和你写的Vue代码不一样,调试起来比较困难。虽然mpvue支持sourcemap,但是效果一般,断点经常不准。而且mpvue的响应式系统,有时候会导致一些数据更新的问题,排查起来很麻烦。
  4. 小程序新特性支持滞后:mpvue需要把Vue语法编译成小程序语法,小程序的新特性和新API,mpvue需要时间来适配,不能第一时间支持。如果你需要用小程序的最新特性,mpvue可能还不支持,需要等框架更新。
  5. 包体积更大:mpvue因为封装了Vue的运行时,包体积比原生小程序和wepy都大。对于包体积敏感的小程序,需要特别注意。mpvue也提供了一些优化方案,比如按需引入、代码压缩等,但是包体积还是比原生大不少。

适合场景

mpvue适合以下场景:

  • 团队非常熟悉Vue,想用真正的Vue语法开发小程序
  • 小程序很复杂,需要最强的组件化能力
  • 有Vue项目需要迁移到小程序,或者需要复用Vue的代码和生态
  • 对性能要求不是特别高,特别是低端手机的性能
  • 对包体积不是特别敏感

五、我们的选择和建议

对比了这几个框架之后,我们团队最后是怎么选择的呢?

我们的选择是:根据项目的具体情况,选择合适的框架,不追求统一。

  • 对于简单的小程序,页面不多,逻辑不复杂,我们用原生小程序开发,因为原生最稳定,性能最好,也没有额外的学习成本和框架风险。
  • 对于中等复杂度的小程序,我们用wepy开发,因为wepy的组件化能力比原生强,开发效率更高,而且性能比mpvue好一些。
  • 对于复杂的小程序,或者有Vue项目需要迁移的,我们用mpvue开发,因为mpvue的组件化能力最强,开发体验最好,还能复用Vue的生态。

当然,这只是我们团队的选择,每个团队的情况不一样,选择也会不一样。下面给一些通用的建议:

建议一:根据项目复杂度选择

  • 简单项目:原生小程序
  • 中等复杂度项目:wepy
  • 复杂项目:mpvue

建议二:根据团队技术栈选择

  • 团队不熟悉Vue:原生小程序
  • 团队熟悉Vue,但是对框架稳定性要求高:wepy
  • 团队非常熟悉Vue,想复用Vue生态:mpvue

建议三:根据性能要求选择

  • 对性能要求很高,特别是低端手机:原生小程序
  • 对性能要求中等:wepy
  • 对性能要求不高:mpvue

建议四:根据包体积要求选择

  • 对包体积很敏感:原生小程序
  • 对包体积中等敏感:wepy
  • 对包体积不敏感:mpvue

建议五:小项目先验证,再大规模使用

不管选择哪个框架,建议先拿一个小项目验证一下,看看框架的稳定性、性能、开发体验是否符合你们的需求,再决定是否大规模使用。不要一上来就把所有项目都换成某个框架,万一框架有问题,返工成本很高。

六、使用框架的通用踩坑经验

最后,分享一些使用小程序框架的通用踩坑经验,不管用哪个框架,这些坑都可能遇到。

坑一:setData性能问题

不管用哪个框架,最终都是编译成原生小程序代码运行,都会有setData的性能问题。要注意:

  • 不要频繁调用setData,尽量合并成一次调用
  • 不要一次setData太多数据,尽量只setData需要更新的数据
  • 不要在循环里调用setData
  • 长列表用小程序的原生组件(比如recycle-view),不要自己实现

坑二:框架版本问题

小程序框架更新比较快,不同版本之间可能有不兼容的问题。要注意:

  • 锁定框架版本,不要随意升级,避免因为框架升级导致项目出问题
  • 升级框架版本之前,先在测试环境充分测试,确认没问题再升级
  • 关注框架的更新日志和issue,了解已知的问题和解决方案

坑三:调试困难

用框架开发小程序,调试比原生更困难,因为代码是编译后的。要注意:

  • 熟悉框架的编译原理,了解编译后的代码结构,方便调试
  • 善用console.log,在关键位置打印日志,帮助排查问题
  • 遇到问题,先判断是自己代码的问题,还是框架的问题,可以用原生小程序复现一下,排除框架的问题
  • 关注框架的issue和社区,很多问题可能已经有人遇到过,有解决方案

坑四:小程序新特性支持滞后

用框架开发小程序,小程序的新特性和新API,框架可能需要时间来适配。要注意:

  • 不要急于用小程序的最新特性,先确认框架是否支持
  • 如果需要用框架还不支持的特性,可以用原生小程序的方式实现,或者等框架更新
  • 关注框架的更新进度,了解新特性的支持情况

坑五:团队学习成本

虽然框架的目的是提升开发效率,但是团队学习框架也需要成本。要注意:

  • 选择框架之前,考虑团队的技术栈和学习能力,选择团队容易上手的框架
  • 引入新框架之前,先让团队成员学习和熟悉,拿一个小项目练手
  • 制定团队的开发规范,统一代码风格和最佳实践,减少因为不熟悉框架导致的问题

结语

小程序开发框架,是为了提升开发效率和开发体验而诞生的。每个框架都有自己的优缺点,也都有一些坑。没有最好的框架,只有最适合的框架。

我们团队在选择和使用框架的过程中,踩了很多坑,熬了很多夜,但是也积累了不少经验,提升了开发效率。希望我们的经验,能给正在做小程序开发的朋友一些参考和提醒,让你们少踩一些坑,少熬一些夜。

最后,用一句话总结:框架只是工具,核心还是产品和用户体验。不要为了用框架而用框架,选择最适合项目的框架,把更多的精力放在产品和用户体验上,才是最重要的。

愿每一个小程序开发者,都能选到适合自己的框架,都能开发出优秀的小程序。