Overview of current (JavaScript) frontend architectures

JavaZone, Oslo 2017

Nils Hartmann / @nilshartmann
Oliver Zeigermann / @DJCordhose

Slides: http://bit.ly/ui-architecture-javazone

Central challenge with a complex Web Application

best ui/ux opposes requirement for maintainability

What makes Frontend Architecture so hard?

The "problem" sits in front of the keyboard!

  • everything should be consistent
    • consistent layout (UI)
    • consistent behavior and interaction (UX)
    • consistent display of all data in all components
  • responsive UI even under load
  • everything should load without delay

The Flipside

Maintainability

Of course™ the application shall also be

  • fast and cheap to develop
  • maintainable for decades
  • developed in autonomous teams
  • developed having a consistent architecture
  • matched with skill set of existing developers

In the beginning...

Classic Web Apps

Classic Web Applications

  1. Browser sends HTTP Request
  2. Content is rendered on the Server
  3. HTML is sent back to the Browser
  4. Browser only shows the page to the user
  5. Each interaction repeats this round-trip

Classic Web Apps

Many times an obvious approach...

In enterprise projects, Classic Web Apps are often the "natural" beginning:

  • Java/C# is the language of choice in the backend anyway
  • Java/C# and HTTP/HTML are very well known and understood
  • UI improvements (like simple validations, animations) can be implemented on the client with JavaScript snippets (jQuery)
  • in many cases this might be sufficient

Classic Web Apps

...but: UI/UX capabilities are limited

  • Even Classic Web Apps often contain "SPA-like" parts
    (for example when using JSF components)
  • Mixing client- and server-side rendering leads to confusing architecture and programming model
  • Real costs of this "mixed" approach getting visible during development (when it's too late...)

Classic Web Apps

Limitations? An Example...

And our example is not even that complex... 🤔

Next Step

Single-Page Applications

Single-Page Applications

The app runs completely in the browser

  • only one (single) HTML page that mainly loads JavaScript and CSS
  • runs without significant server part for the UI
  • server only receives and sends data (JSON/REST API)
  • could even work offline
  • can have same UI/UX experience as a desktop app

Single-Page Applications

Components with Templates

A SPA is composed of (business) components:

  • Templates describe the UI of the component
  • But now:
    • Logic is part of the component
    • Logic is a "first-class" citizen and no longer a "loose" snippet (like in jQuery)
    • Logic is fully executed on the client
  • Prominent Frameworks: React, Angular and Vue

Architecture Pattern

Smart and Dumb Components*

*also known as Mediator Pattern with Web Components / Polymer

Smart Components

  • Managing (part of) the application state
  • Contain UI logic
  • Pass parts of the state as immutable data to subcomponents
  • Pass callbacks to subcomponents for interaction
  • Mostly domain-specific, not intended to be reusable

Dumb Components

  • only for presentation, no logic
    • but might contain own ("transient") state
  • have no knowledge or dependencies to their surrounding components
  • children of Dumb Components are usually other Dumb Components (but there are exceptions)
  • reusable

Smart and Dumb Components

Limitations

Mainly with growing and long-living applications

  • "God-like" components: State and logic tend to slowly move up to a few really fat components
  • Distributed, mutatable state makes maintainable and understanding hard
    • Where does the state belong to?
    • In which state is the application?
  • Mash up of framework and UI code (hardens switching the framework)
  • Still open questions regarding the architecture
    • How to handle asynchronous code?
    • How to do proper initialization of the application?
    • How to test the business logic?

Next Step

Redux as an Architecture Pattern

Redux

  • Central state management: one store for whole app, like a database
  • External state management: extract logic from the (UI-)components
It's not only a framework, it's also a pattern (like MVC)

Redux is independent of UI framework

Bindings exist for popular UI frameworks

Redux extracts responsibility out of the UI framework

Redux Pattern

Resulting Architecture

Code Sample: Reducer

Just a function, thus independent of UI Framework


type Greeting = {
	greeting: string;
	name: string;
}
            

type AddGreetingAction = {
	type: 'ADD_GREETING',
	greeting: Greeting
}
            

function greetingsReducer(state: Greeting[] = [], action: AddGreetingAction) {
    switch (action.type) {
        case 'ADD_GREETING':
            // immutable operation, creating new state
            return [...state, action.greeting];
        default:
            return state;
    }
}
            

The only part that is allowed to update state

Different Types of State

Code Sample: Action Creator

Again, just a function independent of UI Framework


async function loadGreetings(dispatch) {
    try {
        const response = await fetch(BACKEND_URL);
        const json = await response.json();
        dispatch({
            type: SET_GREETINGS,
            greetings: json
        });
    } catch (err) {
        console.error('LOADING GREETINGS FAILED:', err)
    }
}
            

The only place where asynchronous operations are allowed

Wrap Up Redux

A UI pattern for User Interfaces

  • Mainstream solution
  • Independent of framework
  • Easy testing of business logic as logic is implemented only in pure functions ("Reducer")
  • Great debugging because of dev tools
  • Works great in large applications with many dependencies between parts / components

Single-Page Apps

Limitations

  • SEO
  • First-Page-Impressions
  • Previewing content, for example:
    • Preview in search result lists
    • Sharing of links in social media apps

Single-Page Apps

First-Page-Impression

Even for a simple Application it can take a while to load and bootstrap until the app is responsive

What comes from Server is an empty page

Next Step

Universal Web Apps

Universal Rendering

  • First-Page-Impression is rendered on the server
  • Not only the markup but also the state is returned from the server
  • (following pages can be rendered on server as well)
  • Links have to be "real" HTML links (no click handlers)
  • Runs without JavaScript on the client (at least partial) after rendered
  • Code shared almost 100% between client and server
  • Supported by React, Angular and Vue

Universal Rendering: First-Page-Impression

Universal Web Apps

Challenges

  • Complete state must be available on the server
    • Need to wait until all async code has been processed!
  • If returned page is invalid: flickering due to re-rendering on the client
    • Different locales on server and client
    • (Rapidly) changing data (timestamps, market rates)
  • The server must run JavaScript (typically it will be Node.js)
  • How to do with Web Components? (headless chrome?)
  • Only helps with "Time to first Meaningful Paint", not with "Time to Interactive"

Who uses modern SPAs?

Is someone really doing this?

  • Twitter Mobile Client: React with Redux
  • Facebook: React
  • Spotify Web Player: React with Redux
  • New York Times: React
  • JavaZone: React with Redux

The Doctor is In

UI / UXMythsArchitecture
20 Can I use links in SPAs? And the back button? Isn't the life time of a JavaScript Frontend Framework measured in weeks? Why should I use frontend logic in the first place?
40 Should I write every SPA as a Universal Application? Can I refactor and analyze JavaScript code? Isn't all my investment lost if I have to change the UI framework?
60 Choose your question Choose your question Choose your question
80 When should I use a classic Web Application rather than an SPA? Can I reuse JavaScript Code? Why is there no established layer model in SPAs?
100 Why care about server roundtrips, isn't the internet fast enough by now? Isn't JavaScript unmaintainable anyway? How does all this work with Microservices?

Nils Hartmann / @nilshartmann
Oliver Zeigermann / @DJCordhose
http://bit.ly/ui-architecture-javazone