- Notifications
You must be signed in to change notification settings - Fork25
ged-odoo/blockdom
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Probably the fastest virtual dom library in the world!
IMPORTANT:blockdom
is just a proof of concept and a place to experiment some ideas. This isnot intended to be used in a real application, no real support will be given! However, it isdesigned to be the rendering engine of theOwl framework!
blockdom
is a very fast virtual dom library. Its main sellingpoint is that it does not represent DOM element by element, but instead block byblock, where a block is an element with all its static content and some specialtags to indicate dynamic content. This allows blockdom to usecloneNode(true)
on blocks and speed up the diff process, since the vdom tree is much smaller.
It features blocks, supports fragments, manage synthetic event handlers and more.Note that it is not a framework. It does not even have the concept of components.blockdom
is intended to be a lower level layer of abstraction, on top of whichother frameworks could be added. See the documentation for a tutorial on thattopic.
Installing using NPM:
npm install blockdom
Installing using Yarn:
yarn add blockdom
https://unpkg.com/blockdom@{VERSION}/dist/blockdom.iife.min.js
For using the latest version:
https://unpkg.com/blockdom/dist/blockdom.iife.min.js
- Reference documentation
- Extending blockdom
- Performance Notes
- Tutorial: make your own framework (chapter 1,chapter 2,chapter 3,chapter 4,chapter 5,chapter 6,conclusion)
Instead of doing something likeh('div', {}, [...some children])
, we canwork in blockdom with a larger unit of dom. For example:
// create block typesconstblock=createBlock(`<div><p>hello</p><blockdom-child-0/></div>`);constsubBlock=createBlock(`<span>some value: <blockdom-text-0/></span>`);// create a blockdom virtual treeconsttree=block([],[subBlock(["blockdom"])]);// mount the treemount(tree,document.body);// result:// <div><p>hello</p><span>some value: blockdom</span></div>
This example shows themount
function. Here is a more interesting example.It is a dynamic list of counters, featuring handlers, lists and dynamic content:
constcounterBlock=createBlock(` <div> <button block-handler-1="click">Increment</button> <span>Value: <block-text-0/></span> </div>`);constmainBlock=createBlock(` <div> <div><button block-handler-0="click">Add a counter</button></div> <div><block-child-0/></div> </div>`);conststate=[{id:0,value:3}];functionaddCounter(){state.push({value:0,id:state.length});update();}functionincrementCounter(id){constcounter=state.find((c)=>c.id===id);counter.value++;update();}functionrender(state){constcounters=state.map((c)=>{consthandler=[incrementCounter,c.id];returnwithKey(counterBlock([c.value,handler]),c.id);});returnmainBlock([addCounter],[list(counters)]);}lettree=render(state);mount(tree,document.body);functionupdate(){patch(tree,render(state));}
Notice that block types are first created, with special attributes or tags such as<block-text-0 />
orblock-handler-1="click"
. What happens is thatblockdom
then processes the block template, find all these special tags/attributes and generatefast functions that will create and/or update these values. The number correspondsto the index of the data given when the block is constructed.
Also, blockdom supports synthetic handlers (meaning: it only setup one actualevent handler on the body, which is an optimisation). To use this feature, onecan simply use the.synthetic
suffix:
constcounterBlock=createBlock(`<button block-handler-1="click.synthetic">Increment</button>`);
It is also possible to setup an handler incapture
mode:
constcounterBlock=createBlock(`<button block-handler-1="click.capture">Increment</button>`);
Theexamples
folder contains the complete code for this example.
In this section, you will find answers to some questions you may have about thisproject.
Is this virtual dom used in an actual project? Not yet ready, but it is usedin the current work on Owl version 2. TheOwl framework 1.xis based on a fork of snabbdom, and as such, does not support fragment. Theversion 2 is not ready yet, but will be based on
blockdom
.This is not a virtual dom, is it? Yes it is. Well, it depends what you meanby a virtual dom. It is not a representation of the dom tree element by element,but it still is a complete representation of what the dom is looking like. So,yes, in that sense,
blockdom
is a virtual dom.Why would you need a virtual dom, in the first place? It depends on yourneeds. Clearly, some frameworks can do very well by using other strategies.However, some other frameworks (such as React and owl with their concurrent mode)need the ability to split the rendering process in two phases, so we canchoose to commit a rendering (or not if for some reason it is no longer useful).In that case, I do not see how to proceed without a virtual dom.
This sucks. blockdom is useless/slow because of X/Y. Great, please tell memore. I genuinely want to improve this, and helpful criticism is alwayswelcome.
blockdom
is inspired by many frameworks: snabbdom, then solid, ivi, stage0 and1more. The people behind these projects are incredible.