Re: [w3c/webcomponents] [templates] Ensure that template instantiation actually improves the platform (#704)

I think we've steered slightly off-track, so I'll try (hopefully :) ) to get back to what I was intended to say (once again, sorry if I get sidetracked again).

There are two parts to this long-winded comment:

1. What I think (and what we should still strive for)
2. What may actually need

## What I think (and what we should still strive for)

In a tl;dr kind of way my thinking comes to this:

> lighterhtml and hyperHTML, based indeed on the same domdiff library, which uses innerHTML once per unique template tag

There are two question arising:

1. In 2019 why is there no better API than dumping blobs of strings into DOM via `.innerHtml`
2. Why are facilities like domdiff not provided natively by the platform?

In my opinion, if we answer and find solutions to these two questions, the entire template instantiation proposal will be rendered moot. To slightly re-word the reasoning behind the proposal:

> The HTML5 specification defines doesn't provide a native mechanism to instantiate <an element> with some parts of it substituted, conditionally included, or repeated based on JavaScript values

And then it does correctly say that:

> making it hard for web developers to combine otherwise reusable components when they use different templating libraries.

The thing is though: is the answer to that a yet another incompatible templating library and syntax? Developers will continue using their own incompatible templating libraries regardless. The reason is simple: any and all templates are limited in functionality and scope. Incompatible templating systems arise because people find that some templating system X is lacking some crucial functionality.

You can see it with Web Components themselves. When they were finalised and started shipping in browsers there was abundant joy. However, just two short years later, the mood has shifted to "web components APIs are a barebones set of low-level primitives aimed at library writers" and people go out of their way to create better more useful abstractions on top. Including pushing everything into strings.

But this was a sidetrack. Let's get back to template instantiation. Among other things mentioned (or shown as use cases):

- it's hard to create DOM via DOM APIs
- it's hard to find and update required parts of the DOM
- it's hard to do multiple updates efficiently
- it's hard to compose actual components (where a component maybe a deeply nested, updatable DOM structure)

The reason is obvious: these things are hard to do because DOM APIs are low level, imperative and verbose. However, it has been proven multiple times that these APIs can be made sufficiently high-level, declarative and succinct even in userland. And that they literally solve all of the problems above:

- create DOM? A breeze with declarative APIs
- find an update required parts? Same
- multiple updates? Ditto
- compose? These are just nested function calls/ASTs, we compose things all the time

Instead of providing these facilities, the proposal gives us:

- a new templating language (incompatible with everything else)
- that is both very limited in functionality (poorly specified/underspecified `if` and `foreach` as the only control structures) and unlimited in functionality (we can call functions in the host language)
- that is alien to the system (literally nothing in the platform looks or behaves like this)
- that requires a different parser, a different execution model, hooks into the rest of the platform to make it workable
- solves the main use case of composing components poorly, or not at all (you need to nest template elements within template elements within template elements...)
- doesn't specify how you would instantiate elements not from static sources, but from dynamic data (I'm guessing `.innerHtml` again?)

Even though all these problems have been solved dozens of times over by simply providing a better API.

It is my continuing belief that the only right way forward is not to make the platform increasingly weird and complex, but to improve the APIs available to developers and let them figure out what to do with them. 

See part 2 on what developers already do with existing APIs and how we can help them by being a better platform.

## Declarative DOM tree

As I already mentioned a few thousand times :) developers already create DOM trees, diff them, and apply only changes. In userland. Why can't platform itself provide similar APIs and capabilities is beyond my understanding at this point.

However, there are now emerging technologies that may require not just native browser APIs but also a way to provide the browser with a DOM Tree and let the browser figure out what to do. I'm talking about [Phoenix LiveView](https://dockyard.com/blog/2018/12/12/phoenix-liveview-interactive-real-time-apps-no-need-to-write-javascript). The idea is as follows:

- on the server figure out the actual data that has changed
- send it to the browser
- use [morphdom](https://github.com/patrick-steele-idem/morphdom) to figure out minimal updates to the DOM
- update DOM

In the end it does this: ![ezgif-3-7e1ae7100bef](https://user-images.githubusercontent.com/32768/55350845-44b86c80-54bd-11e9-938d-89924ad2963d.gif)

(For crazy versions, see [server-rendered FlappyBird](https://www.richt.co.uk/til/flappy-phoenix-live-view/) or search [Twitter for LiveView](https://twitter.com/search?q=liveview&src=typed_query&f=live)).

Template instantiation and updates would have hard time offering anything of value to an approach like this. A friendly native API to tell the browser exactly what you need or a way to declaratively define and provide DOM trees though? 

- They would basically kill the need for all the VDOM implementations (except tiny wrappers for people who don't like the original API)
- They would obviate the need for a complex solution like template instantiation
- They would actually provide better interoperability because whatever templating system, or a DOM library you have, if in the end of the day it outputs the same DOM structures (or uses the same APIs), it doesn't matter what it looks like. For example, Vue's templates compile to code that is for all intents and purposes indistinguishable from what React's JSX compiles to. And just because these are two different userland implementations they are (somewhat) incompatible. Why not provide a common API in the platform?
- They would let people experiment even more freely with more crazy ideas (60 fps animation entirely provided by the server is already possible, see LiveView links above) because they wouldn't be fighting the limitations of the platform, but be empowered by it.

In my opinion template instantiation and the current (and the only, cca 90s) generation of DOM APIs provide none of that and are very reluctant to move forward.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/704#issuecomment-478696830

Received on Monday, 1 April 2019 18:43:05 UTC