Few months ago, WeChat launched its own solution — Kbone for cross platform development. The solution enables “easy” conversion between Web app and WeChat Mini-Program (MP). In this article, I want to go through the Kbone framework, and the principle behind it.
Ever since WeChat opened its Mini-Program functions, there are thousands of Mini-Program apps been built everyday, from booking a taxi, to ordering food in a restaurant, or getting a movie ticket. Despite the popularity of WeChat Mini-Program, for web developers, we always had the question of how to convert an existing web app into a WeChat Mini-Program. Even both platforms are using similar technologies, there is no easy way of converting between the two. As a result, most people end up with developing two separate applications, thus have to maintain multiple code bases.
To solve this issue, WeChat has launched its own solution — Kbone, to enable developers to build apps that not just working on the Web, but also working on WeChat MP.
What is Kbone?
In a Nutshell, Kbone is an open source web app framework that allows traditional JavaScript web app to be converted to WeChat Mini Program. The framework acts as an adapter that simulates the Web browser, and allows existing web apps to be ported onto WeChat Mini-Program with minimum or even no code changes.
Comparing to its counter-parts, the Kbone framework claims to have the following advantages:
- The framework supports a large set of popular front-end JS frameworks, this includes Vue, React, Preact, etc.
- It has full supports on the Web front-end frameworks, for example, it allows the v-html command in Vue, as well as the Vue-router plugin, without any modification to these frameworks.
- It provides DOM/BOM access, so that Web apps can be easily ported over to WeChat Mini-program without too much code change.
- It comes with native mini-program support, and allows MP native features to be used, for example, live-player component.
- It also provides alternative solutions to DOM features that can not be fully ported to WeChat MP, such as the getComputedStyle function.
How does Kbone work?
In my previous article, I’ve explained the origin of the WeChat Mini-program, and the technology behind it. To quickly revise the difference between WeChat MP and Web based SPA, WeChat MP runs on a two thread model, where both the rendering layer and the core JS logic layer are running inside their own threads. The two threads don’t have much interactions except simple data communication. In other words, we are NOT able to manipulate the UI structure in the rendering layer from the core JS layer.
Let’s take Vue (https://vuejs.org/) as an example, Vue is a popular front-end JS framework for building Single Page Application (SPA). It uses DOM manipulation for front-end content creation. Each Vue template can be seen as a dynamic HTML segment, and the framework generates a DOM tree by assemble all the DOM segments at runtime. The assembling and rendering process is done by the JS core.
<template>
<div id="app">
<div>
<label>Button:</label>
<button type="button">OK</button>
</div>
<div>
<label>Button:</label>
<button type="button">Cancel</button>
</div>
</div>
</template>
The code snippet above is a simple Vue app with two buttons, one button has the text “OK”, and the other button has text “Cancel”. Since the button block has similar HTML content, we can extract it to its own component template, as shown below.
<template>
<div>
<label>Button:</label>
<button type="button">{{text}}</button>
</div>
</template>
This allows us to simplify the original HTML block into smaller chunk with sub-components. Vue will automatically replace the sub-components with HTML content generated at runtime.
<template>
<div id="app">
<button text="OK" />
<button text="Cancel" />
</div>
</template>
WeChat MP, on the other hand, doesn’t have DOM tree. Instead, each MP component is defined using a WXML template and WXSS style file. To convert the Vue app into WeChat MP, we will need to translate the Vue template into its equivalent WXML template in MP. This approach is great for simple application, however, it doesn’t work when the application gets more complex. Also it is not possible to find an equivalent counterparts for every Vue components.
Simulate the DOM tree using MP custom component
The engineers from WeChat have come up with a creative way of solving the DOM tree problem, they decide to build a DOM tree simulator in MP using the custom component. In WeChat MP, a custom component is often used to create reusable UI blocks, and one important feature of custom component is self-reference.
Let’s assume that we have a DOM tree with three types of elements/nodes: DIV, Input Field and Label/Text, where each DIV can have more DIV, Input field, or Label. To simulate this DOM tree structure in MP, we can create a custom component (custom-dom) in MP as follow.
<!-- Input Field Node -->
<input wx:if="{{attrs.name === 'input'}}"/><!-- DIV Node -->
<view wx:elif="{{attrs.name}}">
<custom-dom wx:for="{{children}}" />
</view><!-- Label/Text Node -->
<text wx:else>{{text}}</text>
Here we translate the custom component as a DOM node that can be either a DIV, Input field, or Text. DIV nodes will be resolved into MP view. Input fields are translated into MP input, and label/text will be translated to MP text component. As shown in the diagram below, we put the root DOM node into MP, and convert that into a custom-dom node, and then apply the same transformation to all the children nodes.
As a result, the DOM tree can be fully translated into an equivalent structure in MP using custom component. This gives us a solution to the DOM tree issue.
Event Listener Simulation
However, DOM tree isn’t the only challenge faced by MP developers. The event system triggered by DOM elements are also different from the events on WeChat MP. Therefore, we will also need to translate between the DOM tree events and the MP events, and a good place to have this implementation is in the custom component node.
Kbone has an event simulator in the custom component, and the simulator listens for events triggered by different user actions. Once those events are received, they are translated into DOM event and passed onto the DOM tree. Framework such as Vue will handle those event using its logic, and pass the result back to DOM, which gets translated into DOM simulator and custom components. Again, the same DOM tree simulation comes into play, and generates the corresponding UI changes based on the event.
Both the DOM API simulator and the custom component are the two fundamental building blocks that supports the Kbone framework.
Performance
Even the conversion of DOM node into custom component seems to be a good solution, it also comes with its own drawback. Keeping one DOM node per custom component will require a lot of resource, and not ideal for large and complex Web apps. To solve this issue, the KBone framework introduces a few optimisation approaches, such as breaking a DOM tree into smaller sub-trees, and convert each sub-tree into a custom component rather than one component per node. This approach helps to reduce the number of custom component required for each Web app.
To give you an idea of how fast Kbone apps are rendered, here are some performance tests done by the Kbone team from WeChat.
The left side blue bar shows the rendering time used by Kbone framework, and the right-side bar shows the time used by normal MP WXML pages. As you can see, Kbone consumes less time as comparing to WXML when dealing with apps with small number of DOM nodes (100–300 nodes). As the node number grows, Kbone start to use more rendering time than WXML. That’s why WeChat recommend use native WeChat MP solution for pages with more than 1000+ DOM nodes, and for apps with smaller number of DOM nodes, Kbone can be the better option. Performance is a major limitation on Kbone when it comes to apps with large DOM structure.
How to use KBone?
There are three ways to get started with Kbone: Kbone Cli, Kbone templates, and Webpack.
Use Kbone Cli
If you are starting WeChat MP development from skretch, and have not yet chosen a front-end framework, this will be the option to go for.
First, make sure you have node installed on your machine. Run the following command to verify your node installation.
$ node --version
v11.10.0
You should get something like “v1x.x.x” if you have node installed, otherwise, go to NodeJS for node installation.
Install Kbone cli in your machine
npm install -g kbone-cli
Create a new Kbone project
kbone init my-app
Start the development using WeChat IDE, you can run the app at anytime using the following
// run as WeChat Mini-Program
npm run mp
// run as Web app
npm run web
// build as Web app
npm run build
Use Kbone Project Templates
For people who wants to start with a specific framework, Kbone has provided a number of project templates. Here are the template links on GitHub:
You can clone those project templates, and start working on them with your chosen framework.
Use Webpack
For more advanced users, or people who wants to contribute to the Kbone framework, you can use webpack (https://webpack.js.org/) to package the solution directly into your WeChat Mini-Program. Here is a mp webpack plugin (https://wechat-miniprogram.github.io/kbone/docs/config/).
Summary
The Kbone framework is a good solution for building cross platform compatible WeChat Mini-Programs, especially for building simple CRUD applications. Even the solution has its own limitations, such as the rendering issue on pages with large number of DOM nodes. This is still a great initiative, to push for the wide adoption of WeChat MP as an app platform. Also for developers who need to maintain multiple code bases, this could be a saviour.