Tokamak
Tokamak copied to clipboard
Stateful views in static HTML renderer and hydration support
This would allow an arbitrary app compatible with TokamakDOM to be rendererd to a static HTML. This is a prerequisite for working hydration of static HTML to allow seamless integration between apps rendered with both renderers.
Here's how it could work:
- An arbitrary app that already works with TokamakDOM is supplied to the TokamakStaticHTML renderer producing HTML output. Maybe the HTML renderer would need a flag to specify whether it produces an HTML to be hydrated or a stand-alone HTML. While the latter is what we do right now, the former would link to the
bundle.js
ordev.js
entrypoints in its<head>
, which would load the WebAssembly app linked with TokamakDOM. [Sidenote: maybe this hydration setup with<head>
adjustments should happen incarton
? I imaginecarton
could drive the whole process 🤔 OTOH, with proper server-side rendering this step could be more dynamic, where involvingcarton
may not be desirable. Imagine a Vapor app that does this pre-rendering on the fly with different sets of inputs passed to the app (i.e. different user IDs), callingcarton
every time on every request doesn't make much sense from the performance perspective.] - The WebAssembly bundle of this app linked with TokamakDOM is then produced. Both the HTML from point 1 and the WebAssembly/JS polyfill bundle can then be supplied to an HTTP server/CDN. Again, note that the HTML output supplied here is not empty as it is usually served by
carton dev
, but contains the HTML "snapshot" of the app rendered from the initial state. - When a user opens their browser and opens the app page, the HTML bits that were pre-rendered open almost immediately (assuming that the HTML snapshot of the app in its initial state is not too big)
- After some delay, the actual WebAssembly bundle loads in the browser, with TokamakDOM bits rebuilding the mounted views tree. It wouldn't need to create new DOM targets, just establishing references from mounted views to existing DOM targets coming from the pre-rendered HTML should be enough.
The benefit of it is that users see something on their screens almost immediately without waiting for the whole app to load, which is currently exacerbated by the binary size produced by the SwiftWasm toolchain. The initial state for most of the apps doesn't have to be complex, just a simple throbber that lets users know that the app is loading would be an improvement in most cases.