You know those super cool backticks-for-strings in new JavaScript?
let emotion = `happy`;
let sentence = `Chris is feeling ${emotion}`;
Besides the variable interpolation in there being mighty handy, the do multi-line strings wonderfully, making them great for chunks of HTML:
const some_html = `
<div class="module">
<h2>${data.title}</h2>
<p>${data.content}</p>
</div>
`;
That doesn’t look overly different than JSX does it?! Maybe we’d do something like that as a React component:
class MyModule extends React.Component {
render() {
return
<div class="module">
<h2>{this.props.title}</h2>
<p>{this.props.content}</p>
</div>;
}
}
But what if we don’t really need React, or any other fairly-large-ish JavaScript framework?
What if the only thing we want is the ability to render HTML templates and also really efficiently re-render them when we need to, like React is known for?
As far as I understand it, that’s what projects like lit-html are for. As I write, it’s a pretty new library from Google and the Polymer folks.
It allows you to define an HTML template with regular template literals, like this:
import { html, render } from './lit-html.js';
const helloTemplate = (data) => html`
<div class="module">
<h2>Hello ${data.name}!</h2>
<p>${data.content}</p>
</div>
`;
Then you call the render function, passing it that template, the data, and where you want it rendered:
let data = {
name: "Chris",
content: "Just trying to figure stuff out."
}
render(helloTemplate(data), document.body);
Then say the data changes… you call render again:
data.name = "Sammy";
render(helloTemplate(data), document.body);
And this is where lit-html shines. It’s smart enough to only update the parts of the DOM it needs to.
Here’s a little comparison where some data is changed, then the templates re-rendered. If we innerHTML the whole thing, well, the entire DOM is changed. With lit-html it just changes smaller inner parts.
Here’s a little video where you can see the DOM-updating difference:
There is another project along these lines too. I don’t know quite enough to judge, but it’s a bit older and I believe it’s a bit more robust. It’s called HyperHTML.
HyperHTML also allows you to create templates and render them. And most importantly rerender them efficiently.
Here’s a demo where the data comes from the Quotes on Design API and inserted into a template:
See the Pen Trying HyperHTML by Chris Coyier (@chriscoyier) on CodePen.
Kinda cool that these mini-libraries exist that do useful things for us, so when situations arise that we want a feature that a big library has, but don’t want to use the whole big library, we got smaller options.
Relevantish: https://twitter.com/ebidel/status/763843570327441409
And here’s the Polymer Summit video where lit-html was introduced: https://www.youtube.com/watch?v=ruql541T7gc&feature=youtu.be
Thanks a lot for this post Chris, it’s great to see hyperhtml and lit-html are gaining interest every day more!
If I can suggest a little change to your hyper-example,
<a href=${data.link}>(link)</a>
is actually all you need to render that link (no array as attribute, no quotes needed).I’ve also created a hyper vs lit comparison, regardless it’s still early days for lit-html and probably it’s not fully up-to-date, but at least developers can have a better idea of what’s possible to do with one micro library, or another.
Last, but not least, if you’d like to compare this pattern against most famous frameworks out there, there is a page for that, and it’s fully template-literals-to-dom driven ;-)
I noticed this in the example in the Google presentation. Can you explain why no quotes are needed? What if there is a space or some other character that would break the attribute that is provided by user data that ends up in the data.link value?
You can use quotes if you like, although React users don’t usually quote attributes.
Anyway, the documentation explains pretty much everything you’d like to know about hyperHTML attributes.
Also please do not confuse hyperHTML with Google lit-html ’cause hyperHTML was born 7 months ago and it’s not a Google library.
Are you actually presenting evidence that one method is more efficient than the other? I didn’t see any data presented to contrast the two.
Just because more/less of the DOM is being updated doesn’t seem like it’s proof of efficiency. There may be an underlying assumption that all DOM updates are the most inefficient than any other action you can perform.
Also, since the text being updated in quotes doesn’t have a wrapping element, it doesn’t clearly indicate that only the text was updated an not the full element. All it shows is that the browser highlights it that way.
I would challenge too, that even if there is a performance difference, what is the cost? Often (very often) performance seeking is detrimental to a project, until the very last stages, which I would argue may be too late to change a library/code base to achieve.
Ok, so I watched this video (Chris linked it in a comment)
And in this video he calls lit-html an “experiment”, “sneak preview/peak”, and it’s “very very experimental and under development”. sigh
When google get’s it out of BETA, call me. And then I will take the best ideas, and roll my own. I have framework anxiety now. ALL of the systems I have built over the past 20 years that used frameworks have been forced into updates, just because the frameworks were updated. Vanilla JS, here I come. And Google easily (in my opinion) has the worst track record of any company of supporting it’s libraries, APIs, services, etc… of any tech company. Hands down. Lit-html’s best ideas will end up else where, and I won’t touch it with my worst enemies keyboard and text editor.
He trumpets javascript string literals, and I agree, this is the future of templating. Maybe a marriage between mustache and the literals will come about some how? (or something similar)
He says a primary goal of Lit-html is performance when updating the DOM. I predict this will eventually become less important as any new features brought forward from this system (and the many others like it that he noted) will be added to JS or the browser, or the browser will just make DOM updates faster and more effiecient all on their own. Just like how jQuery’s selector system was adopted into the core of JS/CSS. (querySelector() and querySelectorAll() anyone?)
(finally understand how react JSX works from this video… it’s not real js or html, it’s rendered by a pre-processor, eww. Not sure how this got so popular, maybe I am old fart, but I see all this stuff as a fad.)
I don’t think any of the examples using template literals escape HTML properly. Shouldn’t escaping be used? In this example, I’m using
lodash.escape
:hyperHTML escapes automatically unless you opt in as HTML through an Array or through
{html: content}
.I think Chris left interpolations inside arrays on purpose to let you play but both lit-html and hyperHTML are safe/escaped by default.
You can find more in both projects documentation. No need to use lo-dash (hyperHTML also provides an escape if you really need it for some reason)
well, react has redux or mobx , a store, easier ways to works with the back end, but I get the spirit
Not sure how easeir it is, but viperHTML provides 1:1 compatible API on NodeJS.
The currently fastest HNPWA (hnpwa.com) is indeed powered by viperHTML on the backend, as 100% SSR, and picked up later on on the client, sharing the exact same templates, via hyperHTML.
hyperHTML project deserves more attention. I am looking forward to give it a try. It looks so promising!
Very interresting, and the most important to me, its ..simple !
You may also use the FetchAPI instead of axios
I’m a fan of JSRender which is another similar project – by the creator jQuery Templates from back in the day
https://www.jsviews.com/#jsrplaying
That’s yet another template syntax to remember, the difference here is that you use native template literals interpolations: nothing new to learn ;-)
Heyyyyy another one:
https://github.com/stasm/innerself