Server-side Microfrontends

Voxxed Days Singapore -  30th - 31st May 2019

Server-side Microfrontends

About Me

  • Software Engineer at Standard Chartered Bank

 

  • Currently working in:
    • Scala
    • Kotlin
    • Typescript

 

  • Also DevOps
  • Community involvements:
    • OSS project maintainer
    • Singapore Scala Meetup group organiser
    • Engineers.SG volunteer

 

               _hhandoko

               hhandoko

               hhandoko.com

Agenda

Overview of microfrontend architecture:

  • The concept and core ideas
  • Technology options

Microfrontends learnings from Standard Chartered:

  • Context and adoption rationale
  • Architecture and technology choices
  • Challenges and benefits
  • Future considerations

Overview of Microfrontend Architecture

Overview of Microfrontend Architecture

Overview of Microfrontend Architecture

What are microfrontends?

Core ideas:

  • App is a composition of features owned by independent teams
  • Each team has a distinct area of business or mission
  • A team is cross-functional and develops its features end-to-end

Notes:

[1] - https://micro-frontends.org/#what-are-micro-frontends

Also known as:

  • Frontend Integration for Verticalised Systems
  • Self-contained Systems

 

Comparable concepts:

  • Microapps in mobile

Extends the concept of microservices to the frontend.

Existing architectures

Notes:

[1] - https://micro-frontends.org/ressources/diagrams/organisational/monolith-frontback-microservices.png

Desired architecture

Notes:

[1] - https://micro-frontends.org/ressources/diagrams/organisational/verticals-headline.png

Microfrontends (in one pic)

Notes:

[1] - https://micro-frontends.org/ressources/screen/three-teams.png

Technology options

  • Single-SPA meta-framework
  • Multiple SPAs, each in different locations (contextual paths)
  • Web Components / custom elements
  • Client Side Includes (CSI)
  • Edge Side Includes (ESI)
  • Server Side Includes (SSI)
  • IFrames

Microfrontend as an architectural and

team organisation approach,

not technology stacks

Context

Context

Context

Problems and challenges

Reinvention(s):

  • Functionality overlap between different services and apps
  • Monolith UI code are not easy to port between projects
  • Domain knowledge are spread
  • Enhancements are not uniformly applied to all services and apps

Problems and challenges (cont'd)

Intrinsic dependencies:

  • Immense coordination effort to push a change to production

 

Dynamic coupling:

  • Services (API) and apps (client) links can be brittle
  • Compensate by using various testing methodologies (e.g. integration, contract-based)

Goals

Goals

Goals

Maximise reuse

Restructuring teams around business domains and capabilities:

  • Customer Profile
  • Customer Portfolio
  • Recommendations
  • etc.

Knowledge on specific domain can be transferable across regions and markets.

 

Team composition remains fluid, but enable better continuity from project to project.

Better isolation

Integration on 'last-mile':

  • Feature development happens on one vertical until the point of integration.

 

Independent deployment:

  • Each vertical can set its own development cadence and release schedule.

 

Risk containment:

  • Complexity can be contained in one vertical, and the bugs along with it.
  • Tests are 'cheaper' to run.

Architecture

and

Technology

Architecture

and

Technology

Architecture

and

Technology

Server-rendered web app

Customer requirements indicate that we were going to build a content-heavy web application, with only limited interactivity.

Notes:

[1] - https://cdn-images-1.medium.com/max/1600/1*NJMQCgyMShhjYx6dE_pbRw.png

[2] - https://medium.com/@areai51/microfrontends-an-approach-to-building-scalable-web-apps-e8678e2acdd6

[3] - https://2018.ar.al/notes/the-documents-to-applications-continuum/

Other considerations

Complexity lies in data sourcing and aggregation:

  • Do we really need SPAs?
  • Do we really need Javascript?

Offline first and PWAs:

  • Viable alternative, but far more complex

 

CPU utilisation vs network latency:

  • High network latency

 

First microfrontends?

  • Bring your DevOps A-game!

Alternatives

skatejs:

  • Web components / custom elements SSR

 

node-tailor:

  • Streaming layout service

 

markojs:

  • Async fragment loading

Notes:

[1] - https://skatejs.netlify.com/

[2] - https://github.com/zalando/tailor

[3] - https://markojs.com/

Edge Side Includes

Server Side Rendering:

  • Renders viewable page, then extend with interactivity
  • Only small difference from full client-side development
  • Supported by popular Javascript SPA frameworks

Edge Side Includes:

  • Renders page as-is by embedding content
  • Small markup language, proposed as a spec to W3C
  • Supported by CDNs and caching delivery providers

Notes:

[1] - https://en.wikipedia.org/wiki/Edge_Side_Includes

[2] - https://medium.com/walmartlabs/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8

ESI with nodesi

Customisations:

Replaced good-guy-http with Axios for consistency with the rest of the apps, contextual logging, tuneable retry strategy, and Bearer token header embeds.

Subset of ESI standard with a Promise-based interface.

Notes:

[1] - https://github.com/Schibsted-Tech-Polska/nodesi

<esi:include src="http://example.com/1.html"
             alt="http://bak.example.com/2.html"
             onerror="continue"/>

Technology choices

Stacks:

  • Typescript + Express + EJS
  • Java + Spring Boot + Thymeleaf
  • PostgreSQL
  • Kafka

 

Build Tools:

  • Gradle
  • Backpack (Webpack)

Technology choices (cont'd)

Infrastructure:

  • BitBucket + JIRA
  • Jenkins
  • Artifactory
  • Rundeck
  • OpenShift

 

Others:

  • Docker and Docker compose

Typescript + Express + EJS

Optimise for Time to First Render:

  • nodesi load fragments concurrently
  • Server-side DOM manipulation prior to rendering
  • HTML response minification
  • GZip response compression
  • HTTP/2 (SPDY) web server support

Future considerations:

  • Server-side SVG graph generation
  • Partial page refresh a la SPAs:
    • Component-specific custom scripts with jQuery
    • DOM patching with morphdom

Notes:

[1] - https://github.com/spdy-http2/node-spdy

[2] - https://github.com/patrick-steele-idem/morphdom

Java + Spring Boot + Thymeleaf

Optimise for clarity:

  • Reduce 'magic', more explicit code flow

 

Optimise for fast response and small payload:

  • Session-bound cache
  • GZip (gz) response compression

Future considerations:

  • Brotli (br) assets compression
  • Typed template engine
  • Other web frameworks:
    • Spring WebFlux
    • Micronaut
    • Quarkus
    • http4s
    • akka-http

Notes:

[1] - https://github.com/fizzed/rocker

[2] - https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux

[3] - https://micronaut.io/

[4] - https://typelevel.org/cats-effect/datatypes/io.html

Page interaction

Progressive enhancements:

  • Working page interaction on first render, additional interactivity after script loads

 

Agreed conventions:

  • Navigation trigger methods
  • Common vendor scripts

Future considerations:

  • Use data-* attributes to pass additional data for actions / interaction

Development Experience

Development Experience

Development Experience

Minimal context switching

Monorepo for each vertical:

  • Deployment module
  • Data module
  • Service / UI module

Services are broken down into small modules which are shared by runtime artifacts (i.e. apps).

 

End to end development within a (domain) boundary.

Multiple environments

Various environment-specific configurations:

  • Spring Boot configuration profiles
  • node-convict
  • dotenv

 

Service mocks and API-compatible alternatives:

  • H2 in local, Postgres elsewhere
  • Mock LDAP server to simulate SSO

Multiple environments (cont'd)

Development setup and standalone mode via Docker compose:

  • End-to-end UI development
  • Standalone preview mode:
    • Each service can be expanded to its full functionality
    • Each service can be replaced with one from other environment

Development Overhead

Promote shared resource as a library:

  • Styling-related resources (e.g. SASS, vendor JS, common assets, etc.) as an npm package
  • Deployment manifest generator (Nodejs-based) as an npm package
  • Jenkins shared library
  • Docker base images and layers

Development overhead (cont'd)

Three types of resources available:

  • JSON (via REST API)
  • HTML fragment
  • HTML page

JSON for external service consumption.

 

HTML fragments are the resource used for embedding in the web application.

 

HTML page format is used during development to provide an indication how the component will look and behave.

Observations

Observations

Observations

User Expectations

Implicit assumptions from modern web and mobile apps:

  • Content 'jank' when performing page actions due to page reload
  • Lack of immediate UI feedback from actions (e.g. loading spinner, content placeholders)
  • Features that comes for 'free' in the Javascript ecosystem (e.g. table sorting)

Actual vs Perceived Performance

Good (+ resilient) on poor connection:

  • First page load ~200kb:
    • ~90kb custom webfonts
    • ~30kb jQuery
    • ~50kb styles + interactivity plugins
  • Subsequent page loads ~5kb (+ scripts)

Scalability

Will it scale?

  • Performance is inline with other, similar microservices architecture
  • Low-footprint front-end
  • Time to first byte is dependent on the critical path on concurrent fetch of (remote) UI components
  • Server-side response optimisation, if enabled, adds 7 - 14ms overhead

Questions
and
Answers

Questions
and
Answers

Questions
and
Answers

Thank You!

Thank You

Image Attributions:

- https://www.vecteezy.com/vector-art/192201-seamless-memphis-background

- https://www.vecteezy.com/vector-art/275088-memphis-pattern-design

- https://www.pexels.com/photo/white-painted-wall-1939485/

Made with Slides.com