A lightweight library to update DOM and persist state. IE: React diffing with html instead of JSX (bring your own templating language).
JSX is great but there are so many other nice alternatives. React is great but it's clunky and opinionated.
This is inspired by diffhtml, morphdom and my knowledge from tusk. I set out to create a no nonsense "dom to dom" diffing algorithm that was fast and compact.
- ~800 bytes min/gzip.
- Minimal API.
- Keyed html elements (
data-key
orid
to shuffle around nodes). - Use whatever you want to generate html.
npm install set-dom
<script type="text/javascript" src="set-dom.js"></script>
<script>
define(['set-dom'], function (setDOM) {...}); // AMD
window.setDOM; // Global set-dom if no module system in place.
</script>
const setDOM = require("set-dom");
// We will use handlebars for our example.
const hbs = require("handlebars");
const homePage = hbs.compile(`
<html>
<head>
<title>My App</title>
<meta name="description" content="Rill Application">
</head>
<body>
<div class="app" data-key="home-page">
{{title}}
{{#each frameworks}}
<div data-key={{name}}>
{{name}} is pretty cool.
</div>
{{/each}}
</div>
<script src="/app.js"/>
</body>
</html>
`);
// You can replace the entire page with your new html (only updates changed elements).
setDOM(document, homePage({
title: "Hello World.",
frameworks: [
{ name: "React" },
{ name: "Angular" },
{ name: "Ember" },
{ name: "Backbone" },
{ name: "Everything" }
]
}));
// Or update individual elements.
setDOM(myElement, myHTML);
- setDOM(HTMLEntity, html|HTMLEntity) : Updates existing DOM to new DOM in as few operations as possible.
Just like React (although slightly different) set-dom
supports keyed nodes.
To help the diffing algorithm reposition your elements be sure to provide a data-key
or id
attribute on nodes inside a map. This is optional but key for performance when re-ordering/modifying lists.
Another key difference from React is that set-dom
simply can't tell when you are rendering an entirely different component. As such it is good practice to use data-key
when you know that most of the html will be discarded (like when rendering an entirely different page) to skip the diffing process entirely.
Sometimes it is required to simply escape the whole diffing paradigm and do all of the manual dom work yourself. With set-dom
it is easy to include these types of elements in the page using a special data-ignore
attribute.
Any elements that have a data-ignore
will NEVER be diffed. The only thing set-dom
will do for you in this case is automatically add and remove the element.
You can also easily override the attributes used for both keying and ignoring by manually updating the KEY
and IGNORE
propeties of set-dom
like so.
// Change 'data-key' to 'data-my-key'
setDOM.KEY = 'data-my-key'
// Change 'data-ignore' to 'data-my-ignore'
setDOM.IGNORE = 'data-my-ignore'
Benchmarks are available on the vdom-benchmark website.
- Use
npm test
to run tests.
Please feel free to create a PR!