loading...

Unite Server-Side rendering and Single-Page applications

kapouer profile image Jérémy Lal ・2 min read

This sums up my findings when writing https://github.com/kapouer/window-page.

A web page is defined by its url pathname and query.

phases

· route

Bootstrap initial document that loads scripts and stylesheets.

· build

Scripts and stylesheets loaded during route are available.

Build document depending on pathname.

· patch

Document has been built.

Modify document depending on query.

· setup

Initialize User Interface (animations and stuff).

Register event listeners on document's body.

· close

Cleanup User Interface.

Unregister event listeners on document's body.

prerendering

document.visibilityState == "prerendering"

Two equivalent scenarios:

  • server-side prerendering (jsdom...)
  • browser prerendering (safari...)

The functions bound to these phases must be run:

  • route
  • build
  • patch

and document is serialized as HTML.

rendering

All other cases.

Prerendered HTML is loaded along with scripts and styles, then the functions bound to these phases must be run:

  • setup

navigation

Can happen through History API, or by following links, submitting forms, etc...
All of which must be properly intercepted.

If only current query changes, only the functions bound to this phase must be run:

  • patch

Otherwise it is:

  • close
  • route
  • build
  • patch
  • setup

Or, if route replaces current document by fetching a prerendered document:

  • close
  • route
  • setup

credentials

route, build, patch phases will typically fetch data through HTTP: credentials can be passed along to these requests if needed.

custom elements reacting to patch phase (query changes)

In this framework it must be done manually, either by calling directly an element's update method, or firing an event on current document, or delegating to a singleton manager.

additional comments

  • at the time of writing the module, asynchronous events were not a thing yet, so i had to implement my own promise chains and double them with synchronous events to be able to listen for changes even before the router library was not yet loaded (which can be needed when doing complicated stuff with iframes).

Discussion

pic
Editor guide