Hi! I've started working on a server renderer for lit-html templates, and wanted to share it here in case anyone thinks it may be a good starting point for an official renderer. The lit-html-server package is still available on npm, but I've published it as a scoped package in case it doesn't fit with the current plans:
I've tried to be faithful to (most of) the lit-html semantics and behaviour, while also emphasising rendering performance in a production environment (ie. streams, limited object/instance creation, and no html parsing). Here is a list of completed and planned features:
html and svg template functionsrender(template) function returning a Node.js Readable streamstring, number, boolean, null, undefined)?.@)The streaming implementation is based on the stream-template library by @almost (of which I'm also a contributor). As a performance optimisation, however, instead of returning a Readable stream instance for every template, lit-html-server prefers strings over streams, and only deopts to streams for (nested) stream and Promise value types (render(template) will always return a stream even if template is a string, however). In general, this should result in a significant performance increase (see this issue).
I've tried to handle attributes in a way that is logical for static html rendering, and that also conforms to existing lit-html behaviour. Attribute values missing quotes are wrapped in quotes, and attribute names that are prefixed with binding characters are handled as follows:
?: boolean bindings remove the ?name=${value} if falsey, and retain the name if truthy.: property bindings remove the .name=${value}@: event handler bindings remove the @name=${value}Obviously, the current handling of attributes only makes sense in a static html world, and I haven't tried to address a strategy for re-hydration or any form for bootstrapping lit-html on the client.
As mentioned above, my immediate plans are to add iterator support and begin porting directives, in addition to more tests and documentation. After that, I hope that others from the lit-html team/community may be able to begin planning a strategy for re-hydration/bootstrapping.
Please feel free to weigh in with ideas/comments here or at https://github.com/popeindustries/lit-html-server/issues
There's a lot to unpack here, but I just wanted to pop in to say that this is very exciting!
I have previously gotten most of lit-html itself working in node with a forked version of undom, but hadn't tackled rehydration. That experiment definitely made me think that a seperate server implementation could do some things better like streaming, and of course that property and event handler bindings only make sense if you are deeply rendering custom elements (which I'm somewhat skeptical of for various reasons).
Independently, I made a simple html tag for server rendered pages (for a blog system), which worked really well. lit-html-server seems like a much, much more complete version of that.
Thanks for posting this!
Added classMap/styleMap directives, and will now try and synchronize version numbers with the main lit-html project.
This is amazing! Could we get an example repo to get us started?
Added this to my collection: https://github.com/web-padawan/awesome-lit-html
@aadamsx the only example available right now is probably this silly perf test (~4000 req/sec on my 3+ year old MacBook, in case you were curious 馃槈)
Maybe I should take a look at updating this lit-element todo app with SSR?
closing because of updates outlined in #786
Most helpful comment
Added this to my collection: https://github.com/web-padawan/awesome-lit-html