“Kbone 是一个致力于微信小程序和 Web 端同构的解决方案。”
首先我们来看下普通Web端框架,以Vue框架为例,一份Vue模板对应一个组件,在代码构建阶段编译成调用Dom接口的JS函数,执行此JS函数就会创建出组件对应的Dom树,从而渲染到浏览器页面上。 然而,小程序是双线程的,并没有Dom树的概念,逻辑层和视图层完全分离,逻辑层是一个纯粹的JSCore,开发者可以编写JS脚本,但是无法直接调用Dom/Bom的api, 没有任何浏览器相关的实现。
在小程序中,视图层和逻辑层的交互是通过数据和时间驱动的。
因此,要实现跨端同构,问题是:怎么将web端代码转为小程序代码?
目前业界流行的第三方跨端框架们,常规做法都是:静态编译兼容。
原理是把代码语法分析一遍,然后将其中的模板部分翻译成对应的跨端需求的模板(微信小程序、支付宝小程序、H5、APP等)。
静态编译最大的局限性是无法保证转换的完整性,因为Vue模板和WXML模板的语法并不是直接对等的,Vue的特性设计也和小程序的设计无法划等号,这自然就导致了部分Vue特性的丢失。
比如像Vue中的v-html指令、ref获取Dom节点、过滤器等就通通用不了。
除了Vue自身的特性外,一些原本依赖Dom/Bom接口的Vue插件页无法使用,例如Vue-Router。
Kbone是通过提供 适配器 的方式来实现同构,即运行时兼容,而非静态编译。
Kbone的适配器核心包含两个部分:
miniprogram-render:仿造Dom/Bom接口,构造仿造Dom树;
miniprogram-element: 监听仿造Dom树变化,渲染到页面,同时监听用户行为,触发事件。
仿造Dom树和浏览器的运行时对比:
利用内置组件和自定义组件的自引用来进行递归,创建组件树。
如图,自定义custom-dom为递归自引用组件:
递归的终止条件是遇到特定节点、文本节点或者children空节点。
在创建出组件树猴,将Dom节点和自定义组件实例进行绑定,以便后续的Dom更新和操作。
kbone这里还对节点数进行了优化:
如果一个dom节点对应一个自定义组件的话,就会创建很多自定义组件,这样会很浪费开销,这里做了子树的合并,也就是说3层才创建一个自定义组件,节省开销。
优化前:17个dom=17个自定义组件;优化后:17个dom=4个自定义组件,蓝色那个是单节点,会合并到上面的树;
dom 子树作为自定义组件渲染的层级数是可以通过配置传入,理论上层级越多,使用自定义组件数量越少,性能也就越好。
一棵很大的 Dom 树,一次性 setData 到视图层,可能会超过 setData 的大小限制(1024kB),拆分成多棵子 Dom 树,然后分批的 setData 到视图层,可以节省开销。
小程序的事件是视图层到逻辑层的通讯方式,事件绑定在组件上,当被触发时,就会执行逻辑层中对应的事件处理函数。
小程序的捕获冒泡是在视图层view端,因此逻辑层在整个捕获冒泡流程中各个节点接收到的事件不是同一个对象,小程序事件的捕获冒泡和阻止冒泡等操作必须在WXML模板中生命,无法使用接口实现。
为了能够让web端和小程序端的事件系统行为一致,kbone除了仿造了一份Dom树外,也把整个事件系统仿造了一份,即在仿造Dom树上进行捕获冒泡。
当自定义组件监听到用户的操作后,就将事件发往仿造Dom树,后续自定义组件监听到的同一个事件的冒泡就直接忽略。
当触发改节点,仿造Dom树接收到事件后,再进行捕获和冒泡,让事件在各个节点触发。
官方已经提供了kbone-cli可以用来快速开发:
用npm全局安装kbone-cli
可以根据自己的技术栈选择不同的开发模板:React/Vue/Omi/Preact
然后就可以愉快的进行开发啦~
生成的demo项目结构如下:
demo中包含了多页跳转、vue-router、vuex等的使用示例,以及mp-webpack-plugin的配置示例。
对于多页面的应用,在 Web 端可以直接通过 a 标签或者 location 对象进行跳转,但是在小程序中则行不通。同时 Web 端的页面 url 实现和小程序页面路由也是完全不一样的。
其中,有一部分两端差异的业务逻辑功能,也给出了3中不同的解决方案:
利用vue-improve-loader,在构建时对dom树节点进行删减,在需要提出的节点加上check-reduce属性 利用reduce-loader,将业务中不需要被打包的代码进行去除,使用行内loader和环境变量来判断 使用样式隐藏,即设置不需要显示的节点样式为 display:none
在实际开发中,还会碰到一些细节,例如:
kbone由于目前在快速发展期,更新迭代非常迅速,以下特性是对比了8月份的版本和11月份版本,可以看出已经解决了近2/3的问题。
详细了解了kbone之后,我们来分析下小程序技术框架到底应该怎么选?
没有跨端需求,只需要微信小程序 ==> 小程序原生 web端转小程序 or 两端 or 想要尝鲜 ==> kbone 多端 or Vue 技术栈 ==> uni-app 多端 or React 技术栈 ==> taro 不介意学习新技术栈 ==> wepy 2.0 or chaemeleon
小程序在非常快速的更新迭代,就算是原生框架也还是有一些坑的,因此没有哪种框架是百分之百完美,需要根据业务具体需求以及自身技术栈偏好来进行选择。
https://developers.weixin.qq.com/community/develop/article/doc/0006a6326b8d38e56b998833456813
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8