著做权归做者全部。商业转载请联系 Scott 得到受权,非商业转载请注明出处[务必保留全文,勿作删减]。
蚂蚁雄兵的年代,人人皆可为王。前端
现在早已经是全民联网年代,能够发现本身的父母大姑大姨等亲戚甚至爷爷奶奶,只要他们在使用千元智能机了,不管是看头条仍是微信仍是抖音,都在参与整个互联网的流量和内容的产生,他/她们经过手机消费了本身的时间,同时为全部的产品提供了更多人物画像的行为数据,不管是上翻下翻仍是留言点赞,每个 APP 都是一个独立的平台,而在这两年,冉冉升起的区别于 APP 的新应用平台,非小程序莫属:vue
上图是从阿拉丁公布的数据报告中截取引用过来的,整个 2018 年,基于小程序生态的融资规模是 80 亿,是 2017 年的整整 8 倍,小程序几乎扎根了全部领域的全部层面,并且除了微信小程序,其余小程序小应用也都在布局:git
在整个泛小程序生态崛起的过程当中,许多创业公司都主动登船,小菜也不例外,咱们是在 2018 年 3 月份开始技术预研和拥抱小程序生态,至此 1 年咱们业务上收获颇丰,而技术这里,也略有积淀,就跟你们分享小程序这块咱们的思考和沉淀。github
小菜前端的个别同窗,包括我都有过一些开发小程序的经验,没使用任何框架就用小程序原生语法来实现,但小程序的功能都比较简单,因此也天然没遇到太大的工程挑战,而咱们 2018 年要启动的小程序产品具备两个特征:第一个是功能和交互足够的复杂,第二是迭代速度要很是快,两周就要首版上线,以后每周至少发一到两个版本,基于这样的业务背景,咱们也就毅然的选择使用框架而非原生,但这个决策带来的后期风险也的确超出了咱们的预期。面试
若是咱们再回到一年前作选型,估计仍是会选择框架,但至少不会那么乐观的 All in 其中,而是择时机尽早切回原生(虽然咱们目前已经是半原生)。因此给你们的建议是:若是产品功能相对简单,一二十个页面也没有太奇怪的交互和太大的列表数据量,用框架用原生均可以,开发周期短的话就用框架,实际上市面上看到的绝大多数小程序都不属因而复杂应用,用框架都能很好很快的 hold 住,但反过来假如你要实现的产品交互和前端列表数据量较大,图片图表视频多媒体复杂搜索应有尽有,那么能用原生就用原生。redux
框架的核心价值就是效率,一旦咱们决定使用框架,那么就要把当下及将来市面上可用的小程序框架,作一个必要的比较和选择,这个过程一般会比较纠结。由于截止到 2019 年,还并无一个小程序框架足够足够的好,你们都在六七十分上下,那咱们能够从哪些方面来考虑呢?小程序
小菜前端最初选型框架主要考虑以下几个方面(都很必要但优先级程度自上向下依次下降):微信小程序
整体作选型的路子是优先保产品,再看工程质量及合理性,最后看社区及开发者生态健康程度。缓存
很惋惜,即使咱们考虑了这么多,限于当时(2018 年 3~5 月)的小程序框架生态太过早期也太单薄,咱们最终选择了美团的 MPVue(实际上没得选),但上面的参考项今天看来对你们依然是通用的,当时的比对过程我再给你们呈现下,帮你们加深下这个选型运用的过程:微信
首先针对可否优先保产品,也就是框架成熟程度和开发效率,多端兼容程度这块,咱们实际上只有 wepy,MPVue,Taro 可选,针对他们三个,咱们是这样比对的:
其次,针对工程质量与合理性,也就是框架的配置成本/易用性/拓展性,总体性能这块,咱们是这样评估的:
最后,针对社区/开发者生态,也就是团队成员既有技术栈、社区反馈和生态这块,咱们是这样评估的:
小菜最初的产品端载体主要是 APP 和 PC Web,尤为是 APP,有 7 个之多,因此 RN 的组件化在 2018 年是有过两个大版本的累计了好几十个,但这个对于小程序来说远水解不了近渴,而小程序的页面数目愈来愈多,组件复用变成了刚需,因此咱们开始了小程序的组件建设之旅。
基于 MPVue 在小程序里写组件,也是比较神伤。由于小程序端代码是静态的(即提早编译好的模版), 因此像 HOC 就没办法用了(还有不少其余一些 Vue 语法糖编译不了), 咱们这里用的都是 mixins,基础的 mixins 有不少:
基于 mixins 就能够来设计组件了,一旦决定要抽象出一个组件,咱们主要考虑以下因素:
咱们已经沉淀的组件有:
这些组件里面:
好比 Input/Textarea 组件,它须要重点考虑 UI/功能的耦合,要如何设计?
好比受权/登陆弹窗组件,它须要重点考虑内外部调用的耦合,要如何设计?
好比 Upload Group 组件,它属因而组合组件,要如何设计?
好比语音录制/播放组件,它须要组件性质,要如何设计?
除此之外,组件设计的时候还要兼顾小程序端上与 Vue 的差别性。好比生命周期(组件与页面),在 MPVue 编译完后, Vue 组件生命周期并不会编译成小程序组件的生命周期,说白了就是须要你熟悉两套生命周期: Vue 组件生命周期与小程序组件/页面生命周期。
mounted
永远只会调用一次(除非你在组件或者组件上层挂了 v-if
),而实际上这个组件在小程序里被调用了两次 attached
小程序组件生命周期。beforeMount/onUnload
的问题了。beforeMount/onUnload/其余生命周期
里初始化页面数据及置空全部状态,具体就看你怎么设计和抽象了,最主要的目的仍是让开发者尽量少的感知/手动调用。除了要考虑以上这些问题以外,咱们还须要去解决端上的兼容问题以及框架带来的问题。
微信端的兼容问题简直是层出不穷,不只和机型、系统版本有关,甚至还和微信版本有关。因此当遇到这一类问题的时候,咱们只能求助于 微信开发者社区,期待有相应的解决方案。
框架带来的问题有时候就有点恶心了。好比说 MPVue 并不支持动态的传入 input
的 type
属性,这就致使若是咱们须要文本键盘、数字键盘、带小数点数字键盘等等这一类的 input
时,咱们须要每种类型都写一个 input
组件,平白增长了代码量,而且定位到问题也不方便。
以上咱们探讨了框架选型和组件化设计,最后再回归到咱们认为很是核心的一个能力,就是小程序的原生开发和优化能力,MPVue 编译完的代码运行时的性能在不少场景里并不达到你的要求,好比输入组件的双向绑定之光标闪烁/内容回退,,大数据量之操做延迟等等...... (没遇到过的同窗自行搜索)。总的来讲就是 MPVue 底层对于数据的操做实现的很稀烂,这个问题也只有当咱们将项目作大了才遇到。
当遇到相似上面这种性能问题的时候,就避免不了去寻找解决方案。但所谓的解决方案颇有限,要么换框架,这时候已经上车,全量换框架工程太过浩大不敢想。要么写原生,写原生不只工程量也浩大,并且原生代码的复用成本也难度不小,这就是框架选型带来的后续维护成本和风险了。
但问题是躲不过去的,终究要解决。除了上面这几点须要去衡量的以外, 还要衡量一些非技术因素:
咱们最终仍是决定当部分组件替换为原生组件,好比:
input/textarea
在输入的时候就会出现光标闪烁/内容回滚的异常(缘由就不赘述了),因此使用小程序原生语法重写了 input/textarea
组件,主要目的就是让组件的输入可以脱离 MPVue 的更新,直接组件内部走小程序的 setData
,由于当时 MPVue 尚未对数据更新作 diff
操做,目前听说作了一层 diff
(实际效果你们本身去测评吧)其实除了将组件替换为原生组件以外,咱们还能够去优化原生的 setData
方法,具体内容能够阅读 westore 这个库,进一步提高性能。
最终,咱们的架构慢慢就会变成了这样:Vue 会慢慢成为一个数据注入/数据分析/事件分发三者集合的中心枢纽同样的存在,底层是由各类高性能的原生组件,上层是由 Vue 来分发事件给不一样组件,注入数据到不一样组件里,收集埋点行为/事件。
这样一个现状依然有它新的问题,首先是多端复用成本低,如今还没法一套代码在 H5/小程序里所有通用,其次是小程序原生学习成本仍是比框架要高,这对于不熟悉原生的同窗都是一个不小的技术学习成本。
当下来看,咱们以前选择的 MPVue 已经不能很好地支撑业务需求了。其一是由于 Vue 与咱们的主体技术栈的分割,二来 MPVue 并不能支持跨多个平台开发。
跨多平台开发已是当下的一个迫切需求。假如一个需求须要维护多端的代码,那么势必会须要更多的前端资源投入,这个成本是难以接受的。所以咱们也开始考虑究竟是使用市面上相似 Taro 这样的框架仍是选择自研,二者的选择都有各自的好处。选择 Taro 这样的框架可以让咱们迅速进入开发,可是长远来看免不了可能会出现 MPVue 相似的维护问题;选择自研的话虽然不会存在维护上的问题,可是会短时间内须要投入更多的前端资源。
以上这些问题就是咱们当下遇到的一个困境,选择任何一个方案均可能对未来形成巨大的问题,就好比当初咱们选择 MPVue 那样。
Scott 近两年不管是面试仍是线下线上的技术分享,遇到许许多多前端同窗,因为团队缘由,我的缘由,职业成长,技术方向,甚至家庭等等缘由,在理想国与现实之间,在放弃与坚守之间,摇摆不停,心酸硬扛,你们能够找我聊聊南聊聊北,对工程师的宿命有更多的了解,有更多的看见与听见,Scott 微信: codingdream,也能够来 关注 Scott 跟进个人动态。