由于小程序使用了模板的方式开发,但是我们惯用的 react 却完全使用了虚拟 dom,很多时候让我们写起来非常不适应,甚至使用 remax 之类的库来解决问题。那么为什么小程序要使用模板呢?

模板的优势

为什么支付宝小程序使用了模板呢?因为微信使用了。那为什么微信要使用呢?

编译优化

首先就是模板的第一个好处 可以做的编译态的优化,这一点是虚拟 dom 做不到的。模板在开发者写出来之后页面的大体结构就已经确定了。比如 Button ,他就是一个按钮。这样的好处可以让小程序把 button 直接渲染为一个 native 的组件,性能非常好。还有在手机端非常难解决的 input 框键盘弹出后的行为问题,这个东西原来有很多奇技淫巧,微信小程序直接帮你解决了。

小程序团队在这方面也下了很大的功夫,地图,视频,文本框,文本渲染(直接砍掉了) 这些功能每一个都是老大难,但是现在小程序已经解决的差不多了,除了 input 还遥遥无期。

image.png

因为是模板所以你感觉不到底层做了什么改变,所以可以对模板进行很多的性能优化,即使算法大改,你的产品可能什么也感觉不到,这也是 vue 的不优化性能高于 react 的原因。 vue 不需要 shouldComponentUpdate,也不需要 memo,这些功能的心智负担是很重的。

传统

模板非常传统,虽然你要学一些新语法,但是你看起来真的很想一个 html,里面写了一些js,css。同时也可以接入的 html 的原来的生态,有不少人喜欢别的模板语法,你可以接入起来一起看一起用。

传统这个东西会让人天生有熟悉感觉,对于新人开发者来说,这个就可以一锤定音,让人选择使用这个技术框架。虽然模板需要新的语法,但是写 JSX 也需要学习 js,对于新人来说学 html 比 js 快多了。

html 和 css 一直是虚拟 dom 的传统弱项。模板可以对这个有更好的支持,虚拟 dom 虽然也可以搞,但是样式隔离,metas 的设置等都会让人觉得充满挫败感。

模板分割

模板天然就是隔离的,所以你可以很开心的在一个模板里面写很多代码,然后在另外一个模板上写同样放飞自我的代码。

依然是熟悉的 HTML 和 CSS,但是可以放在一个文件里。而且你还可以使用你想要的预处理器,比如 LESS, Jade, Coffee, Babel,都可以。你迁移原来的代码到 模板也会更加简单,因为几乎是相同的。

虚拟 dom 的优势

一切都是 js

虚拟 dom 的组件化要模板方便太多了,很多代码库都有 react.cloneElement 之类的操作,还有基本操作 toArray(children) 这样的操作,让代码的灵活性得到了极大的增强。

image.png

JSX 在逻辑表达能力上完爆模板,你可以使用完整的编程语言 JavaScript 功能来构建你的视图页面。比如你可以使用临时变量、JS 自带的流程控制、以及直接引用当前 JS 作用域中的值等等。 开发工具对 JSX 的支持相比于现有可用的其他模板还是比较先进的 (比如,linting、类型检查、编辑器的自动完成)。

更灵活也为各种 Provide 的诞生建立了基础,在外面包了一个组件里面的组件样式面目全非,这个对于模板来说是很难的。这对造轮子来说就很爽了,下面的 umi 的各种包裹,一顿操作下来,你什么代码都没写,大部分的功能已经抽象出来了。

image.png

可测试性、重构

可测试是一个组件库最基本的功能,这个对于虚拟 dom 来说是传统优势项目,毕竟虚拟 dom 和运行环境是无关的。一个函数手起刀落就能解决。

重构也是同样的道理,因为都是 js,所以重构的时候可以依赖编辑器的静态分析,如果加持了 typescript ,那么重构起来行云流水,非常简单。

模板在这方便天然有弱项,小程序到现在都没有很好的测试方案,我们做的只能是尽量把小程序做小。vue 虽然实现了,但是也是通过在 node 中模拟 dom 的方式来实现。写起来还是没有虚拟 dom 来的爽。

总结一下

为什么喜欢虚拟 dom 和 jsx 的方式,其实就是因为喜欢写 js,html 的只是个 DSL,css 虽然强大,但是不正交。只有 js 写起来非常简单,我们写界面本质上都是在写的下面这个函数。

image.png

在抽象度方面,还是虚拟 dom 的抽象能力更强。