Tokamak icon indicating copy to clipboard operation
Tokamak copied to clipboard

Stateful views in static HTML renderer and hydration support

Open MaxDesiatov opened this issue 3 years ago • 0 comments

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:

  1. 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 or dev.js entrypoints in its <head>, which would load the WebAssembly app linked with TokamakDOM. [Sidenote: maybe this hydration setup with <head> adjustments should happen in carton? I imagine carton could drive the whole process 🤔 OTOH, with proper server-side rendering this step could be more dynamic, where involving carton 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), calling carton every time on every request doesn't make much sense from the performance perspective.]
  2. 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.
  3. 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)
  4. 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.

MaxDesiatov avatar Aug 11 '20 09:08 MaxDesiatov