Try “asm-dom” that is virtual DOM library by using WebAssembly
Tags: asmdom, javascript, virtualdom, webassembly
Published: 2018-03-13 03:19:20

---
title: Try “asm-dom” that is virtual DOM library by using WebAssembly
published: true
description: 
tags: asm-dom, js, virtual-dom, webassembly
---
# What is “asm-dom”?
https://github.com/mbasso/asm-dom
asm-dom is a virtual DOM library using WebAssembly. Its “diff” and “patch” algorithm of virtual DOM are implemented by WebAssembly and it’s a minimal implementation so it doesn’t have high function as React. I expect it is very fast by WebAssembly.

[The date of the initial commit](https://github.com/mbasso/asm-dom/commit/1e619cab3895d846bf389ceb0c175f0b2f02292e) is 2017/2/26 so it’s a year old.
[Copyright and Lisense](https://github.com/mbasso/asm-dom#copyright-and-license) includes the name of [“snabbdom”](https://github.com/snabbdom/snabbdom). It maybe related to snabbdom.
>Simon Friis Vindum, 2015 as part of project snabbdom
# Usage
It can be written by C++ but I used JS like WEB in this time.
```
npm i --save asm-dom
```
```
npm i -D arraybuffer-loader
```
I added `webpack` and `webpack-dev-server` to bundle by webpack.
```
npm i -D webpack webpack-dev-server
```
`webpack.config` is like this. I added `arraybuffer-loader` to load `.wasm` file. I refer to [the document for JS](https://github.com/mbasso/asm-dom/blob/master/docs/js.md).
```js
var resolve = require('path').resolve;

module.exports = env => {
  const dist = env.prod ? 'docs' : 'dist';
  return {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: resolve(__dirname, dist),
      pathinfo: !env.prod,
    },
    node: {
      fs: 'empty'
    },
    devtool: env.prod ? 'source-map' : 'eval',
    devServer: {
      contentBase: resolve(__dirname, dist),
      historyApiFallback: true,
      compress: true,
      port: 9000
    },
    module: {
      loaders: [
        {
          test: /\.wasm$/,
          loaders: ['arraybuffer-loader']
        }
      ]
    }
  };
}
```
# VS "virtual-dom"
I compared speed of "asm-dom" with ["virtual-dom"](https://github.com/Matt-Esch/virtual-dom) that is a virtual DOM library. I measured the time of replacing 30000 text elements of `<div>`. I used Chrome ver61.

# "asm-dom" won
"asm-dom" is 2 times faster than "virtual-dom". I never imagined this result. WebAssembly is awesome. I would like to compare also only "diff" and "patch" algorithm of React.

asm-dom result
![asm-dom result](https://thepracticaldev.s3.amazonaws.com/i/y1xl0j3aljfcvx33rivb.png)

virtual-dom result
![virtual-dom result](https://thepracticaldev.s3.amazonaws.com/i/jsteuw6z6irszihrwzbw.png)

# The code for measuring
I uploaded the code into [this](https://github.com/SatoshiKawabata/asm-dom-vs-virtual-dom).
You can define DOM like [hyperscript](https://github.com/hyperhype/hyperscript) so make nodes by `h()` and apply diff by `patch()` like as virtual-dom.

asm-dom code
```js
import init from 'asm-dom';

init().then(asmDom => {
  const { h, patch } = asmDom;

  const root = document.getElementById('root');

  let vnode = h('div', {}, []);
  patch(root, vnode);

  let cnt = 0;
  const id = setInterval(() => {
    console.time('apply patch in 30000 elements');
    const list = [];
    for (let i = 0; i < 30000; i++) {
      list.push(
        h('div', {}, [ Math.random() + '' ])
      );
    }
    const newVnode = h('div', {}, list);
    patch(vnode, newVnode);
    vnode = newVnode;
    console.timeEnd('apply patch in 30000 elements');
    cnt++;
    if (cnt >= 10) {
      clearInterval(id);
    }
  }, 100);
});
```
virtual-dom code
```js
const h = require('virtual-dom/h');
const diff = require('virtual-dom/diff');
const patch = require('virtual-dom/patch');
const createElement = require('virtual-dom/create-element');

let cnt = 0;
let tree = h('div', {}, []);
let rootNode = createElement(tree);
document.body.appendChild(rootNode);

const id = setInterval(function () {
  console.time('apply patch in 30000 elements');
  const list = [];
  for (let i = 0; i < 30000; i++) {
    list.push(
    h('div', {}, [ Math.random() + '' ])
    );
  }
  const newTree = h('div', {}, list);
  const patches = diff(tree, newTree);
  rootNode = patch(rootNode, patches);
  tree = newTree;
  console.timeEnd('apply patch in 30000 elements');
  cnt++;
  if (cnt >= 10) {
    clearInterval(id);
  }
}, 1000);
```