Closed theSherwood closed 4 years ago
I'm going to throw on. Since I've been curious about this for a long time. This by far the most interesting feature of Sinuous to me (mostly as it is the most different from what I do with Solid). Solid's html
tag I Just-in-Time compile the template into something very similar to what I do with the JSX, which means incredible performance (Maybe like a 3% hit over precompiled JSX). But it also means code bloat because I'm basically shipping htm
in the client code. It's almost 5kb extra minified on its own! The benefit of course is that it is much faster than than any HyperScript version and the user just gets this optimization for free without thinking about it. They just write the code like normal and it is optimal. The same uncompiled html
tagged code for Solid should be about 15% more performant (in something like JS Frameworks Benchmark).
See https://medium.com/better-programming/the-fastest-way-to-render-the-dom-e3b226b15ca3?source=friends_link&sk=5ae1688dde789e46cecf5c976e708da5. Keep in mind I'm using Solid's slower Proxy in all those examples except Solid Signals so the HyperScript/Tagged Template versions should be about 5% faster.
Now Sinuous neck and neck with compiled approaches on the benchmark. Why is that? Sinuous html
runs on HyperScript which is almost identical to Solid's and that on its own is much slower(still faster than like Preact, but slower than libraries like Inferno or uhtml). However, the template
mechanism allows Sinuous to escape the multicast nature of observables and computations and with a special syntax use a similar at runtime construction technique. This template approach has a 2nd benefit in that it doesn't have to worry about disposal in the same way so it tends to be more performant when removing rows from a table. It removes almost all reactive overhead making it about the same something like mikado, or stage0.
It would be really helpful to understand the limitations and restrictions here. Can they be nested? Can I build my whole view with nested templates
? Nested Components? Nested conditionals and lists? Could template
ing everything be a compilation advantage for htm
? Or is this reserved a special purpose tool to optimize specific scenarios where you might need to repeat the same thing in a large list?
sorry for the slow response, it's been a while since I worked on the template module. trying to remember how it all worked :) great questions though.
I'll try to put together an example, I think conditionals should work. One extension I built on top of template
is the sinuous/render
module. it works like lit-html.
mm looking at the code of render
this is pretty much what you're after I think. have a look:
some more context on sinuous/render
: https://github.com/luwes/sinuous/issues/58
I see that makes sense. But those components would need to be wrapped in a computation to update if they were tied to reactive data. That's perfectly fine. It's just a little bit different.
The template
mechanism is still able to do fine-grained updates if I understood properly with those helper wrappers. In that it builds a proxy of sorts. So you could say update a row label without rerunning the whole list. Does that mechanism support nesting?
ah right, no inline it doesn't support conditionals. it would have to be added as a value of the template data. that's not so user friendly. https://components.studio/edit/GZOlHjjvYJIB0e8IdQ7Q
Oh ok, that makes sense. Basically there are no expressions in the template so you basically need to set it as an observable. Ok well good to know. Doable in a pinch but not exactly general purpose. Cool thanks.
ah right, no inline it doesn't support conditionals. it would have to be added as a value of the template data. that's not so user friendly. https://components.studio/edit/GZOlHjjvYJIB0e8IdQ7Q
Can we create a nested template like this:
const PhoneLog = template(() => html`
<div class="card col-md-4 col-sm-6">
<h5 class="card-header d-flex justify-content-between">
<a href="/person?q=${t('phone')}">${t('phone')}</a>
<a href="tel:${t('phone')}"><i class="fas fa-phone"></i></a>
</h5>
<div class="card-body">${t('entries').map(e => template(() => html`
<p class="card-text"><strong>${t('time')}:</strong></p>`)(e))}
</div>
</div>`);
@luwes I've been looking at the template package, which seems interesting, but I can't seem to get it to work with conditionals. Does it work with conditionals and do you have an example of that?