Server Client State Business Logic Routing Presentation Logic (incl. Templating) Look (CSS) & Behaviour (JS) JSON-API JSON-Client Business Logic State JSON
Server Client State Business Logic Routing Presentation Logic (incl. Templating) Look (CSS) & Behaviour (JS) JSON-API JSON-Client Business Logic State Routing Presentation Logic (incl. Templating) HTML Hydration JSON
In a nutshell • Moving routing and presentation logic to the client moves other responsibilities to the client as well • Additionally, we need more infrastructure and coordination and increase duplication and indirection
Portable app • Use Web technologies to build a “native app” • One code base for all platforms • VS Code, Atom, Slack... • ⚠ more resource intensive than a native app iCloud
Reduced Observability • On a server, we can write logs and catch and collect exceptions • This is also possible on the client, but is much more complex and error-prone
Single-Threaded (Mostly) • JavaScript is executed in a single thread* • I/O operations are executed outside of that thread • But a CPU task blocks the thread* • If we execute a lot of business logic, we block the thread • If the thread is blocked, the entire browser tab becomes unresponsive *With Web Workers we can execute code on a separate thread
JavaScript in the Browser... • is time intensive • is error-prone • the errors are less observable • the code is only executed in one thread (mostly) • needs to run in a variety of browsers
Hybrid approach • Routing and most of the state stays on the server • The page and most of the components are rendered on the server • Individual, complex components can use a library like Preact or Vue and manage their state locally
Custom Elements • Define new HTML Elements and their behavior in JavaScript • Native support in modern browsers • No support for data binding and templating
Transclusion • Embed (parts of) other pages • The control over the exact content remains in the target document • This could even be a separate system • Much looser coupling than JSON • Transclusion doesn't even need business logic • h-include, embeddable-content
Integration Patterns • Links/Forms for most things • Use Transclusion mainly for content, not highly interactive components • Great for personalized fragments to improve cacheability of the main content • Use client side JavaScript for complex components
Speed up Page Transitions • We want to parse and execute CSS & JS only once • We don't want to see a white page when transitioning between pages • PJAX was introduced by GitHub in 2011 • PJAX enhances links, such that they only switch the content of the instead of the entire document • Turbolinks is a modern variant of PJAX
“The Web Way” “The App Way” Initial Load Fast Slow (can be improved with Hydration) Page Transitions Fast (using PJAX) Fast Integration Patterns A lot of choices (within and between systems) Rather monolithic Resilience High Low Offline Mode Hard to impossible Possible Portable Native App Turbolinks? Possible