HTML templates should solve isomorphic web but don't
Browsers ship with something you could technically call a native templating system, but which learned nothing from the decades of prior art (asp, php, erb, django / jinja, coldfusion probably) about what kind of syntax and API people will put up with.
The HTML template element makes no sense and offers nothing that you couldn’t get by cloning a normal element and populating it with javascript.
In particular, it doesn’t do a good job of data-binding:
if I wanted to unpack a JSON object into an HTML <template>
I’d need to use a bunch of javascript.
Given that 50% of vue / react’s value prop is unpacking json into HTML, this is a major shortfall.
A browser templating standard with tolerable syntax and native data-binding would vastly improve life for anyone who works in this space. Read on.
- Isomorphic web
- AJAX without javascript
- DOM customElements is hefty
- Collapsing tech stacks is hard but worthwhile
Isomorphic web
React + Vue rule – they make it easy to build and maintain powerful UX. React + Vue suck – for pages that can be built statically, they make life worse.
‘Isomorphic web’ means pages that can be rendered consistently by frontend + backend technologies. In a vue / react world, pages end up requiring multiple round trips to render completely (load HTML, load JS, load content). They also don’t always index properly and don’t work on browsers with javascript turned off. (The latter problem might be just a me thing).
Isomorphic is trivial if you’re willing to write every frontend feature twice. Consistent presentation without duplicate work often requires fancy and painful buildsystems which constrain your technology choices.
A usable common standard for browser templating buys us relatively simple isomorphic web, as well as more powerful frontend features without javascript.
The current system IMO has bad separation of concerns – we should use JS to edit and refetch, but we shouldn’t use it to do initial fetch and rendering.
AJAX without javascript
As all of my readers already know, AJAX means that you use javascript to update parts of a page without reloading the whole thing. This is usually in response to user actions, and sometimes in response to long-running open server connections.
An example: I add something to a list, and it’s immediately visible without a full page reload.
Native data-binding templates could make this kind of behavior trivial to implement: submit a form, reload a JSON endpoint afterwards, and the DOM automatically updates because it knows how that JSON maps to the page.
If you do this for a living, you know this situation is not nearly as simple as I presented it – there are lots of ways to add something to a list. But you can cover a lot of base cases with just ‘post, partial update’.
DOM customElements is hefty
MDN’s web components examples need 130 lines of javascript to achieve rudimentary data-binding for a list.
The smallest usable example of anything I can come up with is:
<html><body>
<template id="card">
<h2><slot name="title" /></h2>
<p><slot name="body" /></p>
</template>
<card->
<span slot="title">Hello</span>
<span slot="body">lorem ipsum etc</span>
</card->
<script>
customElements.define('card-', class extends HTMLElement {
constructor() {
super();
const template = document.querySelector('template#card');
this.attachShadow({ mode: 'open' })
.appendChild(template.content.cloneNode(true));
}
});
</script>
</body></html>
That’s a lot of pipe.
Collapsing tech stacks is hard but worthwhile
A standard templating system for web would also enable a next generation of frontend frameworks with smaller bundles and less complexity. There’s so much duplication of templating features across a zillion frontend + backend libraries today. Some of it will stick around, but having a common base would make life easier.
Adding more standards isn’t always a clear win; xkcd readers know this well. But in some cases, a new standard can shrink code size, build time, and run time. I suspect this is one of them.