htmlefet

1.0.1 • Public • Published

HTMLefet

HTMLefet helps you bind data to html in a fast, robust way - using web standards and no more!

(no build step required - looking at you, lit-html)

Basic usage:

<script type="module">
    import {efet} from "https://cdn.jsdelivr.net/npm/htmlefet/htmlefet.js"

    window.state = {
        name: "Inigo Montoystory",
        color: "red"
    };

    // Binding the above object to an html template
    let boundElement = eval(efet())(state, () => `
        <div>
            My name is <span style="color: ${state.color}">
                ${state.name}
            </span>
        </div>
    `);

    // boundElement is a regular html element!
    document.body.appendChild(boundElement);

    // modifying the state
    state.name = "John Cena!!!";
    setInterval(() => state.color = state.color === "blue" ? "red" : "blue", 300);
</script>

Play with it live: https://jsfiddle.net/8k1rvq6a/2/

In the above example, boundElement is a regular DOM element. The only thing that sets it apart is that when a property of state changes, the corresponding expression in the template will be re-evaluated and updated in the element's DOM.

To get a feel for it, you can open the devtools and play with the state object!

All of HTML, Bound

HTMLefet is straightforward - it's just html with js chunks inside. you don't have to learn how to use it. If your knowledge of js and html is a hand, HTMLefet is a well-fitting work glove.

Expressions

<div>my age will be ${state.age + 1} some day</div>

Events

<button onclick="${() => state.clicks += 1}">
    click me baby ${state.clicks} more time
</button>

CSS

<style>
 #thing {
    color: ${state.color};
 }
</style>
<div id="thing">colorful things</div>

You could write a css line (color: red;), or even a whole rule.

Attributes

<input placeholder=${state.placeholder}/>
<div ${state.hidden ? "hidden" : ""}></div>

Nested

let boundElement = eval(efet())(state, () => `
<div>
    ${state.amAlive ? "yes" : eval(efet())(innerState, () => `
        <span style="color: ${innerState.deathColor}">NO</span>
    `)}
</div>
`);

Notice how the inner template uses a different state object: innerState.

Loops

import {efet} from "https://cdn.jsdelivr.net/npm/htmlefet/htmlefet.js"

window.state = {
    friends: [{
        name: "dave",
        isNice: true
    }, {
        name: "Mojojojo",
        isNice: false
    }, {
        name: "harambe",
        isNice: true
    }]
};

let boundElement = eval(efet())(state, () => `
<div>
    ${state.friends.map(friend => eval(efet())(friend, () => `
        <div style="color: ${friend.isNice ? "green" : "red"};">
            ${friend.name}
        </div>
    `))}
</div>
`);

document.body.appendChild(boundElement);

state.friends[0].isNice = false; // Boom

WTF The Fuck? We returned an array of bound elements, each of which is bound to a different friend. When we changed the isNiceness of the first friend, its bound element changed automatically.

keyed logic coming soon...

Web Components

No web rendering library is complete without a showoff of it's intended usage, while comparing it to other frameworks and stating why it's better!

...Coming Soon...

But why?

You're probably thinking "another web rendering library, more garbage, grate success". There are dozens of great libraries claiming to do the same, written by pretty smart people. so what sets HTMLefet apart?

Expression Hooks

HTMLefet maintains two important mappings in the background:

  • properties to expression (state.age is linked to the expression ${state.age / 2 + 7})
  • expressions to DOM Nodes (${state.age / 2 + 7} is linked to the div <div>${state.age / 2 + 7}</div>)

When a property is changed (state.age += 1), it's corresponding expression is re-evaluated, and the result goes into the DOM Node.

It sounds simple, but it has a great advantage over other rendering libs: changes to the state follow with the minimum amount of reactions to make the DOM change.

Lets compare that to React

React claimed to be pretty fast because it took the slowest operation in the web and minimized it: changing the DOM. React keeps a copy of the DOM (called virtual dom), and whenever a rerender is queued, React compares the virtual DOM to the actual one, and changes the diffs.

But there's a problem. Imagine building a component that contains a huge list of all the words, ever. You'd think that you only have to pay once, performance wise: when rendering the list to the DOM. But it's not the case, because whenever you call setState without changing the list, the whole list is still going to be compared to the actual DOM, unless you move that to another component, forcing you to create lots of small and coupled components.

The comparison is not as heavy as actually replacing the DOM, but it's still very heavy when there's lots of stuff on the virtual DOM to compare.

That's one aspect where HTMLefet wins: when some property changes, instead of comparing the whole component, HTMLefet knows exactly what element to change because it holds a reference to it.

Level up: Lets compare to lit-html

TODO: Make sure im not bullshitting about how lit-html works...

Lit-html is the inspiration for this project (alongside lighterhtml). they keep it simple: no binding, user decides when to render. each rendering, the template is evaluated with all the expressions inside it, and puts them inside the DOM with the minimum amount of DOM work possible.

The catch: imagine a website showing two numbers: PI and E, but it calculates them on page load. on the fly

Disclaimer

All of what I said about the performance being good is a speculation, maybe i'm completely wrong - i havent run tests yet, soon i'll update with benchmark results.

Package Sidebar

Install

npm i htmlefet

Weekly Downloads

1

Version

1.0.1

License

MIT license

Unpacked Size

111 kB

Total Files

11

Last publish

Collaborators

  • davest