Why VDOM was necessary
On the other side of web, there were developers who simply used innerHTML to just render html strings into the DOM. That's very bad m'Kay. Here's why-
It parses the html string and re-renders the entire tree on even the smallest change.
Reference to the nodes in the component are lost.
Nodes loose the events attached to them.
It's not safe because any kind of user input will be interpreted as html so the code will be vulnerable to XSS.
One way to solve the problems with the pure DOM manipulation approach is to re-render the entire DOM tree every time your state changes. But as you can tell, that can be extremely slow for large DOM trees. Also, the state of the DOM resets every time we re-render (Eg - input information is lost, focused elements lose focus, etc).
Dawn of VDOM
VDOM to the rescue! What VDOM does is rather than working on the DOM itself, it creates a lightweight copy of the DOM and renders it. Then on each state change, it generates a new VDOM tree with the updated state, compares it to the old one and only patches the changes instead of rendering the entire tree including the static parts. This is a great performance enhancement over rendering the entire tree on every state change.
Here's a simple counter example of VDOM in action with virtual-dom.
ReactJS popularized the use of VDOM. Combined with the power of JSX, it completely changed the way we write UI components.
Problems with VDOM
VDOM is amazing and it brought great performance in the way we work with DOM. But, it is still the DOM we are working with which is pretty slow. Also, a large part of the tree may just remain static for the rest of the runtime but it will still be included in the diff. A lot of excessive computations are done in figuring out where the changes are since it has to compare all nodes in both the trees on every state change. Although React does give us ways to prevent updates for components with the lifecycle callback - shouldComponentUpdate, it is still left largely to the developer to make sure unnecessary computations are avoided.
This is where hyperHTML comes in. HyperHTML uses ES2015's tagged template string literal which is a way to attach functions to template strings and instead of the browser generating the string directly, the gives the developer control over how the string gets templated.
The tagging function can process the data before rendering the string which is where the hyperHTML keeps it's power source. With tagged template, hyperHTML knows exactly what parts of the html is static and what part can change and instead of performing diff on the entire tree looking for changes per node(the VDOM way), it just looks for changes in the dynamic parts of the template. This allows it to make more optimizations while re-rendering the DOM on state change. Also unlike React(JSX), hyperHTML runs on most modern browsers without the need for transpilation.
Here's a hello world for hyperHTML as the ritual demands -
Comparison with React
React loses to hyperHTML in terms of performance. Migrating from React to hyperHTML will not only improve your application's performance, it will also reduce the js bundle size you ship to the client. Also, as hyperHTML doesn't use JSX, you can get rid of the babel preset. Yay! All is well. But if you love the way you write react components and don't want things to change much, the following comparison should help you migrate.
Here's a hyperHTML example -
And here's one in react -
You can go to hyperHTML's website to checkout more comparisons to other frameworks and libraries.
Web Components is the web standard's answer to writing self-contained, reusable components. It provides an API that allows you to write custom elements as components with technologies like custom elements v1, shadowDOM, HTML Templates, etc. The browser support for Web Components is not the great but with the required polyfills you can use it in production today.
HyperHTML integrates seamlessly with the custom elements spec. It lets the developer combine the encapsulation provided by web components with the performance of HyperHTML. There's also the HyperHTMLElement library, which helps you reduce some of the boilerplate involved in writing custom elements with hyperHTML.
Here’s a simple clock example in HyperHTMLElement with shadowDOM -
With hyperHTML’s isomorphic twin ViperHTML you can write isomorphic hyperHTML apps with awesome performance. ViperHTML has support for asynchronous rendering and strings are XSS safe by default.
You can checkout the viperHTML’s Hacker News PWA to see a server-side rendered PWA in action.
A simple and dumb example for ViperHTML’s asynchronous rendering -
VDOM and ReactJS in particular started a revolution in the way we write UI components for the web. HyperHTML presents us with the next step. Suck every drop of performance out of your web app with this amazing library. The simplicity of the API is what makes the developer experience even better.
Visit https://viperhtml.js.org to get started.