SlideShare a Scribd company logo
1 of 66
THE RECIPE FOR
SCALABLE
FRONTENDS
DAN PERSA & MAXIMILIAN FELLNER
10-11-2017
MILAN
2
DAN PERSA
Engineering Lead
@danpersa
dan.persa@zalando.de
3
MAXIMILIAN FELLNER
Software Engineer
@mxfellner
maximilian.fellner@zalando.de
EUROPE’S LEADING ONLINE FASHION PLATFORM
15 countries
21+ million active customers
~3.6 billion € revenue 2016
200+ million visits per month
13.000+ employees in Europe
1.600 tech employees
Visit us: tech.zalando.com
5
ZALANDO FASHION STORE
6
THE RECIPE
FOR
SCALABLE
FRONTENDS
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
SCALING THE TECH TEAM
ATTRACT NEW,
TALENTED PEOPLE
KEEP THE TEAMS HAPPY
ENCOURAGE
INNOVATION
CREATE DIVERSITY
500+
Apps
~1600
Tech employees
2016
2016 2017
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
13
Conway’s Law
“organizations which design systems
...are constrained to produce
designs which are copies of the
communication structures of these
organizations”
MICROSERVICES
TEAM AUTONOMY
INDEPENDENT RELEASE CYCLES
MIX DIFFERENT TECH STACKS
EASY A/B TESTING
SCALING THE ARCHITECTURE
15
TEAMS OWN BACKEND APIS
MICROSERVICES
ON THE
FRONTEND?
17
APIS ARE USED BY A FRONTEND MONOLITH
18
WEBAPP GETS CONTRIBUTIONS
FROM MULTIPLE TEAMS
WORK AUTONOMOUSLY
MIX OF DIFFERENT TECH STACKS
INDEPENDENT RELEASE CYCLES
20
MOSAIC
www.mosaic9.org
21
TEAMS OWN FRAGMENTS
Translation Service
Team Pathfinder
IAM API
Team GreendaleFRAGMENT
Your Team API
Your Team
From Tailor
HTML Render
AJAX APIs
Internal API Client
From Skipper
Cart Service
Team COAST
23
FRAGMENTS USE THE BACKEND APIS
24
LAYOUT SERVICE
25
ASSEMBLED CONTENT IS STREAMED TO THE CLIENT
26
MOSAIC COMPONENTS
JIMMY
27
SKIPPER
Forwards requests to different
endpoints based on request properties:
Host, Path, Method
Cookies, etc.
Streams content from the endpoints
Runtime updates of routing table
github.com/zalando/skipper
28
Tailor is a layout service that
uses streams to compose a web
page from fragment services.
Loads content of all fragments
from the template in parallel.
Offers nice error handling and
fallback features.
github.com/zalando/tailor
29
TEMPLATE
<html>
<head>
<fragment src="http://assets.domain.com"></fragment>
</head>
<body>
<fragment src="http://header.domain.com"></fragment>
<fragment src="http://content.domain.com" primary></fragment>
<fragment src="http://footer.domain.com" async></fragment>
</body>
</html>
HEADER
CART
TAILOR
layout service
CART FRAGMENT
Team COAST
HEADER FRAGMENT
Team Navigation
QUILT
template management API
CART TEMPLATE
TRACKING
TRACKING
FRAGMENT
Team TRCKNG
https://cart.coast.zalan.do
https://eb-fragment.trckng.zalan.do
https://header-fragment-release.navigation.zalan.do
From Skipper
https://zalando.de/cart
31
FRAGMENT JAVASCRIPT
FRAGMENT SKIPPER
router
TAILOR
layout service
CLIENT
STATIC HTML
<button>click me</button>
LINK HEADERS
<script.js>; rel="fragment-script"
<style.css>; rel="stylesheet"
AMD MODULE JAVASCRIPT
define([], () => element => {
element.onclick = () =>
alert('Hello, World!')
})
32
FRAGMENT JAVASCRIPT
FRAGMENT SKIPPER
router
TAILOR
layout service
CLIENT
STATIC HTML
<button>click me</button>
LINK HEADERS
<script.js>; rel="fragment-script"
<style.css>; rel="stylesheet"
AMD MODULE JAVASCRIPT
define([], () => element => {
element.onclick = () =>
alert('Hello, World!')
})
33
FRAGMENT COMMUNICATION
FRAGMENT A
bus.trigger('cart:add', {
sku: 'ABZ123'
});
EVENT BUS
external library
FRAGMENT B
bus.on('cart:add', args => {
const { sku } = args;
});
publish &
subscribe
github.com/grassator/happened
34
HOW IT LOOKS
Header Fragment
Cart Fragment
Tracking Fragment
*Not every fragment has to be visible
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
MOSAIC
IT’S LIVE!
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
SCALING
THE
CONTENT
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
SCALING
THE
CONTENT
SKIPPER
router
TAILOR
layout service
FRAGMENTS
39
FRAGMENT ARCHITECTURE
FRAGMENT SKIPPER
router
TAILOR
layout service
CLIENT
?
MODERN, INTERACTIVE USER EXPERIENCE
DYNAMIC CONTENT
CONSISTENT LOOK & FEEL EVERYWHERE
40
FRAGMENT ARCHITECTURE
FRAGMENT
<div>
<button id="btn">
click me
</button>
<script>
$('btn').click(() =>
alert('Hello!')
)
</script>
</div>
DOESN'T SCALE
Too manual
Inconsistent
Only static content
41
FRAGMENT ARCHITECTURE
FRAGMENT
let x = parseRequest(req)
let data = await fetch(x)
let html = template(data)
res.write(html)
BETTER
HTML templates
External content data
Dynamic responses
DOESN’T SCALE
Still inconsistent
JavaScript is 2nd class
42
FRAGMENT ARCHITECTURE
FRAGMENT
SOLUTION
Reusable, shared components
Isomorphic/universal code
SSR: JavaScript → HTML
*
* generic universal component framework
43
CONTENT .HTML
.JS
SKIPPER
router
TAILOR
layout service
CLIENT
DESCRIBE JAVASCRIPT COMPONENTS WITH JSON
44
DESCRIBE JAVASCRIPT COMPONENTS WITH JSON
type: div
props: null
children:
- type: h1
props: null
children:
- Hello, World!
- type: a
props:
href: https://www.zalando.de
children:
- Zalando Fashion
*
* rendered as YAML for readability
45
LAYOUT .HTML
.JS
SKIPPER
router
TAILOR
layout service
CLIENT
GENERATE CODE AND HTML
USE COMMON COMPONENT LIBRARIES
46
GENERATE CODE AND HTML
<div>
<h1>Hello, World!</h1>
<a href=”https://www.zalando.de”>
Zalando Fashion
</a>
</div>
React.createElement(‘div’, null,
React.createElement(‘h1’, null,
‘Hello, World!’
),
React.createElement(‘a’, {
href: ‘https://www.zalando.de’
},
‘Zalando Fashion’
));
JSON → JavaScript
generateCode()
JavaScript → HTML
renderToString()
47
LAYOUT .HTML
.JS
SKIPPER
router
TAILOR
layout service
CLIENT
GENERATE CODE AND HTML
UNIVERSAL
JAVASCRIPT RUNS
ON THE CLIENT TOO!
48
tessellateverb tes·sel·late ˈte-sə-ˌlāt
to form into or adorn with mosaic
github.com/zalando-incubator/tessellate
49
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
.JSON .JS
TESSELLATE
bundler
CDN
static server
1. parse JSON AST
2. generate JavaScript code
3. compile webpack bundles
4. export static files
50
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
import React from 'react';
import ReactDOM from 'react-dom';
import Foo from 'foo';
import { ComponentA, ComponentB } from 'bar';
export const Root = props => {
return (
<div id="root">
{React.createElement(
Foo, null,
React.createElement(ComponentA, null, 'Hello, World!'),
React.createElement(ComponentB, {
href: 'https://www.zalando.de'
})
)}
</div>
);
};
51
import React from 'react';
import ReactDOM from 'react-dom';
import Foo from 'foo';
import { ComponentA, ComponentB } from 'bar';
export const Root = props => {
return (
<div id="root">
{React.createElement(
Foo, null,
React.createElement(ComponentA, null, 'Hello, World!'),
React.createElement(ComponentB, {
href: 'https://www.zalando.de'
})
)}
</div>
);
};
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
type: foo.default
props: null
children:
- type: bar.ComponentA
props: null
- type: bar.ComponentB
props:
href: ‘https://…’
52
import React from 'react';
import ReactDOM from 'react-dom';
import Foo from 'foo';
import { ComponentA, ComponentB } from 'bar';
export const Root = props => {
return (
<div id="root">
{React.createElement(
Foo, null,
React.createElement(ComponentA, null, 'Hello, World!'),
React.createElement(ComponentB, {
href: 'https://www.zalando.de'
})
)}
</div>
);
};
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
type: foo.default
props: null
children:
- type: bar.ComponentA
props: null
- type: bar.ComponentB
props:
href: ‘https://…’
53
import React from 'react';
import ReactDOM from 'react-dom';
import Foo from 'foo';
import { ComponentA, ComponentB } from 'bar';
export const Root = props => {
const bundledProps = { myValue: 'https://www.zalando.de' };
const mergedProps = Object.assign({}, bundledProps, props);
return (
<div id="root" data-props={JSON.stringify(props)}>
{React.createElement(
Foo, null,
React.createElement(ComponentA, null, 'Hello, World!'),
React.createElement(ComponentB, {
href: jsonPtr.get(mergedProps, '#/myValue')
})
)}
</div>
);
};
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
type: foo.default
props: null
children:
- type: bar.ComponentA
props: null
- type: bar.ComponentB
props:
href:
$ref: #/myValue
54
import React from 'react';
import ReactDOM from 'react-dom';
import Foo from 'foo';
import { ComponentA, ComponentB } from 'bar';
export const Root = props => {
const bundledProps = { myValue: 'https://www.zalando.de' };
const mergedProps = Object.assign({}, bundledProps, props);
return (
<div id="root" data-props={JSON.stringify(props)}>
{React.createElement(
Foo, null,
React.createElement(ComponentA, null, 'Hello, World!'),
React.createElement(ComponentB, {
href: jsonPtr.get(mergedProps, '#/myValue')
})
)}
</div>
);
};
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
type: foo.default
props: null
children:
- type: bar.ComponentA
props: null
- type: bar.ComponentB
props:
href:
$ref: #/myValue
55
...
<div id="root" data-props={JSON.stringify(props)}>
{React.createElement(
Foo, null,
React.createElement(ComponentA, null, 'Hello, World!'),
React.createElement(ComponentB, {
href: jsonPtr.get(mergedProps, '#/myValue')
})
)}
</div>
);
};
export default function render(element) {
const props = JSON.parse(element.getAttribute('data-props'));
ReactDOM.render(<Root {...props} />, element);
}
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
56
TESSELLATE: TRANSFORM JSON INTO JAVASCRIPT
Build portable UMD bundles
Run webpack in memory github.com/mfellner/webpack-sandboxed
Export a root component, export a render function for Tailor
Interface for injected property values
Support JSON Pointers in props { “$ref”: “#/attrs/value” }
Inline props for rehydration
Include external component libraries from npm
{ type: “[node-module-name].[export-name]” }
57
TESSELLATE: RENDER JAVASCRIPT INTO HTML
.HTML.JS
TESSELLATE
fragment
CDN
static server
1. fetch webpack bundles
2. load external data
3. execute JavaScript code
4. render static HTML
renderToString()
58
TESSELLATE: RENDER JAVASCRIPT INTO HTML
Fetch the precompiled bundle …
const code = await fetchBundle()
const { Root } = vm.runInNewContext(code)
const props = await fetchContent()
const element = React.createElement(Root, props)
ReactDOMServer.renderToString(element)
59
TESSELLATE: RENDER JAVASCRIPT INTO HTML
Run the code in the Node vm …
const code = await fetchBundle()
const { Root } = vm.runInNewContext(code)
const props = await fetchContent()
const element = React.createElement(Root, props)
ReactDOMServer.renderToString(element)
60
TESSELLATE: RENDER JAVASCRIPT INTO HTML
Fetch any external content …
const code = await fetchBundle()
const { Root } = vm.runInNewContext(code)
const props = await fetchContent()
const element = React.createElement(Root, props)
ReactDOMServer.renderToString(element)
61
TESSELLATE: RENDER JAVASCRIPT INTO HTML
Render to HTML!
const code = await fetchBundle()
const { Root } = vm.runInNewContext(code)
const props = await fetchContent()
const element = React.createElement(Root, props)
ReactDOMServer.renderToString(element)
62
TESSELLATE: RENDER JAVASCRIPT INTO HTML
Download the code
Precompiled bundle and any dependencies.
Fetch external content
To be injected as properties into the root component.
Send to Tailor
Rendered HTML and links to JavaScript (according to the Fragment API).
63
TESSELLATE
CONTENT
.HTML
.JS
SKIPPER
router
TAILOR
layout service
CLIENT
TESSELLATE
bundler
TESSELLATE
fragment
DATA
MODERN, INTERACTIVE USER EXPERIENCE ✓
DYNAMIC CONTENT ✓
CONSISTENT LOOK & FEEL EVERYWHERE ✓
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
SCALING
THE
CONTENT
SCALING
THE
TECH TEAM
SCALING
THE
ARCHITECTURE
SCALING
THE
CONTENT
RADICAL
AGILITY
MOSAIC
TESSELLATE
x
www.mosaic9.org
@danpersa
@mxfellner

More Related Content

What's hot

Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Fwdays
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs SilverlightMatt Casto
 
Node.js Patterns for Discerning Developers
Node.js Patterns for Discerning DevelopersNode.js Patterns for Discerning Developers
Node.js Patterns for Discerning Developerscacois
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaYevgeniy Brikman
 
Microservices in Scala: Play Framework
Microservices in Scala: Play FrameworkMicroservices in Scala: Play Framework
Microservices in Scala: Play FrameworkŁukasz Sowa
 
Grokking #9: Building a real-time and offline editing service with Couchbase
Grokking #9: Building a real-time and offline editing service with CouchbaseGrokking #9: Building a real-time and offline editing service with Couchbase
Grokking #9: Building a real-time and offline editing service with CouchbaseOliver N
 
4 JVM Web Frameworks
4 JVM Web Frameworks4 JVM Web Frameworks
4 JVM Web FrameworksJoe Kutner
 
Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016takezoe
 
Leveraging Open Source for Database Development: Database Version Control wit...
Leveraging Open Source for Database Development: Database Version Control wit...Leveraging Open Source for Database Development: Database Version Control wit...
Leveraging Open Source for Database Development: Database Version Control wit...All Things Open
 
Functional Programming in Clojure
Functional Programming in ClojureFunctional Programming in Clojure
Functional Programming in ClojureTroy Miles
 
CubeJS: eBay’s Node.js Adoption Journey
CubeJS: eBay’s Node.js Adoption JourneyCubeJS: eBay’s Node.js Adoption Journey
CubeJS: eBay’s Node.js Adoption JourneyPatrick Steele-Idem
 
WebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! FrameworkWebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! FrameworkFabio Tiriticco
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tourcacois
 
Introduction to Play Framework
Introduction to Play FrameworkIntroduction to Play Framework
Introduction to Play FrameworkWarren Zhou
 
Node js training (1)
Node js training (1)Node js training (1)
Node js training (1)Ashish Gupta
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play frameworkFelipe
 
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Fwdays
 

What's hot (20)

Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs Silverlight
 
Node.js Patterns for Discerning Developers
Node.js Patterns for Discerning DevelopersNode.js Patterns for Discerning Developers
Node.js Patterns for Discerning Developers
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and Scala
 
Microservices in Scala: Play Framework
Microservices in Scala: Play FrameworkMicroservices in Scala: Play Framework
Microservices in Scala: Play Framework
 
Grokking #9: Building a real-time and offline editing service with Couchbase
Grokking #9: Building a real-time and offline editing service with CouchbaseGrokking #9: Building a real-time and offline editing service with Couchbase
Grokking #9: Building a real-time and offline editing service with Couchbase
 
4 JVM Web Frameworks
4 JVM Web Frameworks4 JVM Web Frameworks
4 JVM Web Frameworks
 
Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016
 
Leveraging Open Source for Database Development: Database Version Control wit...
Leveraging Open Source for Database Development: Database Version Control wit...Leveraging Open Source for Database Development: Database Version Control wit...
Leveraging Open Source for Database Development: Database Version Control wit...
 
Functional Programming in Clojure
Functional Programming in ClojureFunctional Programming in Clojure
Functional Programming in Clojure
 
CubeJS: eBay’s Node.js Adoption Journey
CubeJS: eBay’s Node.js Adoption JourneyCubeJS: eBay’s Node.js Adoption Journey
CubeJS: eBay’s Node.js Adoption Journey
 
WebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! FrameworkWebSockets wiith Scala and Play! Framework
WebSockets wiith Scala and Play! Framework
 
webworkers
webworkerswebworkers
webworkers
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 
JavaScript Web Workers
JavaScript Web WorkersJavaScript Web Workers
JavaScript Web Workers
 
Web workers
Web workersWeb workers
Web workers
 
Introduction to Play Framework
Introduction to Play FrameworkIntroduction to Play Framework
Introduction to Play Framework
 
Node js training (1)
Node js training (1)Node js training (1)
Node js training (1)
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play framework
 
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
Григорий Шехет "Treasure hunt in the land of Reactive frameworks"
 

Viewers also liked

Mattia Tommasone - What we talk about when we say "web performances" - Codemo...
Mattia Tommasone - What we talk about when we say "web performances" - Codemo...Mattia Tommasone - What we talk about when we say "web performances" - Codemo...
Mattia Tommasone - What we talk about when we say "web performances" - Codemo...Codemotion
 
Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017
Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017
Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017Codemotion
 
Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...
Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...
Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...Codemotion
 
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015Codemotion
 
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...Codemotion
 
Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...
Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...
Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...Codemotion
 
Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017
Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017
Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017Codemotion
 
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015Codemotion
 
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017Codemotion
 
Composable architectures The Lego of IT - Alessandro David
Composable architectures The Lego of IT - Alessandro DavidComposable architectures The Lego of IT - Alessandro David
Composable architectures The Lego of IT - Alessandro DavidCodemotion
 
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017Codemotion
 
Luciano Mammino - Cracking JWT tokens: a tale of magic, Node.JS and parallel...
Luciano Mammino  - Cracking JWT tokens: a tale of magic, Node.JS and parallel...Luciano Mammino  - Cracking JWT tokens: a tale of magic, Node.JS and parallel...
Luciano Mammino - Cracking JWT tokens: a tale of magic, Node.JS and parallel...Codemotion
 
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017Codemotion
 
Downtime is not an option - day 2 operations - Jörg Schad
Downtime is not an option - day 2 operations -  Jörg SchadDowntime is not an option - day 2 operations -  Jörg Schad
Downtime is not an option - day 2 operations - Jörg SchadCodemotion
 
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...Codemotion
 
Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...
Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...
Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...Codemotion
 
Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...
Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...
Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...Codemotion
 
Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...
Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...
Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...Codemotion
 
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...Codemotion
 
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Codemotion
 

Viewers also liked (20)

Mattia Tommasone - What we talk about when we say "web performances" - Codemo...
Mattia Tommasone - What we talk about when we say "web performances" - Codemo...Mattia Tommasone - What we talk about when we say "web performances" - Codemo...
Mattia Tommasone - What we talk about when we say "web performances" - Codemo...
 
Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017
Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017
Rafal Gancarz - Serverless for the Enterprise - Codemotion Milan 2017
 
Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...
Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...
Andrea Ulisse - How to build a scalable serverless IoT architecture on GCP - ...
 
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
 
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
 
Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...
Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...
Lorenzo Barbieri - Serverless computing in Azure: Functions, Logic Apps and m...
 
Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017
Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017
Yan Cui - Serverless in production, an experience report - Codemotion Milan 2017
 
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
 
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
 
Composable architectures The Lego of IT - Alessandro David
Composable architectures The Lego of IT - Alessandro DavidComposable architectures The Lego of IT - Alessandro David
Composable architectures The Lego of IT - Alessandro David
 
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
 
Luciano Mammino - Cracking JWT tokens: a tale of magic, Node.JS and parallel...
Luciano Mammino  - Cracking JWT tokens: a tale of magic, Node.JS and parallel...Luciano Mammino  - Cracking JWT tokens: a tale of magic, Node.JS and parallel...
Luciano Mammino - Cracking JWT tokens: a tale of magic, Node.JS and parallel...
 
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
 
Downtime is not an option - day 2 operations - Jörg Schad
Downtime is not an option - day 2 operations -  Jörg SchadDowntime is not an option - day 2 operations -  Jörg Schad
Downtime is not an option - day 2 operations - Jörg Schad
 
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
 
Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...
Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...
Carlo Ferrarini/Marco Dragoni - How to avoid delivery of unsanitary food with...
 
Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...
Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...
Marco Balduzzi - Cyber-crime and attacks in the dark side of the web - Codemo...
 
Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...
Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...
Thomas Rossetto - Container and microservices: a love story - Codemotion Mila...
 
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
 
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
 

Similar to Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotion Milan 2017

Web Frontend development: tools and good practices to (re)organize the chaos
Web Frontend development: tools and good practices to (re)organize the chaosWeb Frontend development: tools and good practices to (re)organize the chaos
Web Frontend development: tools and good practices to (re)organize the chaosMatteo Papadopoulos
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Nativejoshcjensen
 
Lessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeLessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeRyan Boland
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
Web3Hub-GDSC presentation.pdf
Web3Hub-GDSC presentation.pdfWeb3Hub-GDSC presentation.pdf
Web3Hub-GDSC presentation.pdfmasa64
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityDerek Lee Boire
 
Rails for Beginners - Le Wagon
Rails for Beginners - Le WagonRails for Beginners - Le Wagon
Rails for Beginners - Le WagonAlex Benoit
 
Presentation html5 css3 by thibaut
Presentation html5 css3 by thibautPresentation html5 css3 by thibaut
Presentation html5 css3 by thibautThibaut Baillet
 
Rust: Systems Programming for Everyone
Rust: Systems Programming for EveryoneRust: Systems Programming for Everyone
Rust: Systems Programming for EveryoneC4Media
 
React: JSX and Top Level API
React: JSX and Top Level APIReact: JSX and Top Level API
React: JSX and Top Level APIFabio Biondi
 
Docker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando Tech
Docker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando TechDocker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando Tech
Docker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando TechHenning Jacobs
 
Build 2017 - B8100 - What's new and coming for Windows UI: XAML and composition
Build 2017 - B8100 - What's new and coming for Windows UI: XAML and compositionBuild 2017 - B8100 - What's new and coming for Windows UI: XAML and composition
Build 2017 - B8100 - What's new and coming for Windows UI: XAML and compositionWindows Developer
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesFederico Feroldi
 
Come abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architettureCome abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architettureCommit University
 
Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Melania Andrisan (Danciu)
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveepamspb
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsMykyta Protsenko
 
RichFaces: rich:* component library
RichFaces: rich:* component libraryRichFaces: rich:* component library
RichFaces: rich:* component libraryMax Katz
 
React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi Binary Studio
 

Similar to Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotion Milan 2017 (20)

Web Frontend development: tools and good practices to (re)organize the chaos
Web Frontend development: tools and good practices to (re)organize the chaosWeb Frontend development: tools and good practices to (re)organize the chaos
Web Frontend development: tools and good practices to (re)organize the chaos
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Native
 
Lessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeLessons from a year of building apps with React Native
Lessons from a year of building apps with React Native
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
Web3Hub-GDSC presentation.pdf
Web3Hub-GDSC presentation.pdfWeb3Hub-GDSC presentation.pdf
Web3Hub-GDSC presentation.pdf
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team Productivity
 
Rails for Beginners - Le Wagon
Rails for Beginners - Le WagonRails for Beginners - Le Wagon
Rails for Beginners - Le Wagon
 
Presentation html5 css3 by thibaut
Presentation html5 css3 by thibautPresentation html5 css3 by thibaut
Presentation html5 css3 by thibaut
 
Always on! Or not?
Always on! Or not?Always on! Or not?
Always on! Or not?
 
Rust: Systems Programming for Everyone
Rust: Systems Programming for EveryoneRust: Systems Programming for Everyone
Rust: Systems Programming for Everyone
 
React: JSX and Top Level API
React: JSX and Top Level APIReact: JSX and Top Level API
React: JSX and Top Level API
 
Docker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando Tech
Docker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando TechDocker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando Tech
Docker Berlin Meetup June 2015: Docker powering Radical Agility @ Zalando Tech
 
Build 2017 - B8100 - What's new and coming for Windows UI: XAML and composition
Build 2017 - B8100 - What's new and coming for Windows UI: XAML and compositionBuild 2017 - B8100 - What's new and coming for Windows UI: XAML and composition
Build 2017 - B8100 - What's new and coming for Windows UI: XAML and composition
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala Microservices
 
Come abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architettureCome abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architetture
 
Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and Ops
 
RichFaces: rich:* component library
RichFaces: rich:* component libraryRichFaces: rich:* component library
RichFaces: rich:* component library
 
React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi React 101 by Anatoliy Sieryi
React 101 by Anatoliy Sieryi
 

More from Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyCodemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaCodemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserCodemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 - Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Codemotion
 

More from Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Recently uploaded

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 

Recently uploaded (20)

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 

Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotion Milan 2017

Editor's Notes

  1. Total length: 40 minutes (35m talk, 5m Q&A). License: https://creativecommons.org/licenses/by-nc-sa/3.0 Hello everybody, welcome to our talk, The Recipe for Scalable Frontends.
  2. My name is Dan Persa, I’m an Engineering Lead in the Fashion Store department at Zalando and one of my challenges now, is to lead the team which is building a next generation content management system. I’m also one of the developers who contributed to the Project Mosaic, the one we’ll be talking about today.
  3. Hi, I’m Maximilian Fellner and I’ve been working on web services and applications at Zalando for several years. Recently I developed a new open source project that aims to make frontends more scalable and you’ll learn about that today as well.
  4. Zalando is Europe’s leading online fashion platform. Here are some numbers to show why our recipe for scaling works. It’s because we’re dealing with scaling every day! Our company is present in 15 countries, we have more than 21mil active customers and last year we had a 3.6 billion E in revenue. We have a great team of 1600 talented people in tech.
  5. And here is how our Fashion Store looks like!
  6. Now, that you have an idea about the scale at which our company operates, let’s get to our “Recipe for Scalable Frontends” Every recipe has two important things: The ingredients The instructions We’ll soon discover ingredients related to scalability and ingredients related to frontends, we’ll get our hands dirty and get into the technical instructions as well.
  7. Let’s take a look at the first 2 essential ingredients we will use for our recipe: Scaling the tech team Scaling the architecture Without these two ingredients, scaling the frontend might not even make sense, as the system operates at a such low capacity, that scaling is not a problem worth tackling. Let’s dive deeper and see why each of these two is important.
  8. First we want to be able to scale the tech team. What does this mean? It means attracting new, talented people, to grow the team. The reason you want to scale the team in general, and specifically in our case, the frontend team, is because there are plenty of new features to be added to existing products or new products to be built. Of course, this can’t be achieved if there are more frontenders leaving the company, than coming, so another requirement is to keep the existing team happy. Putting somebody to spend 4 hours every week to deploy a monolith, doesn’t make anybody happy!! Having the frontend developers waiting for a monolith to compile, let’s say, its Java classes, is also not appealing! We want diverse people who are able to see the same problem from different perspectives. The more ideas you have, the more likely it is to find the best one. Diversity leads to innovation. We also want to actively encourage innovation. Innovation is keeping the company on top of the competition and it can be encouraged by organizing hack weeks and giving the teams time to build prototypes and experiment. A happy team is an innovative team. For a happy, innovative team it’s easy to talk about the projects they are working on (like me and Max today) and attract other talented people. As you can see, all four points are interconnected! Let’s look and see how, applying these principles helped our company scale its tech team.
  9. Here is how our tech department evolved over time… as we can see, we started in 2008, with PHP and MySQL, Magento actually :) One of my colleagues created this chart two years ago, to demonstrate the growth of our apps, in comparison to our tech team… What we can see here is more or less linear growth for both the number of employees and apps. Starting 2015, it had to be slightly adjusted.
  10. As you can see, the number of apps exploded! We have more than 500. And since then, we started to have plenty of open source repos in GitHub. The number of people in tech is more than double compared to two years ago. So, looking at this numbers, you might ask yourselves - how can this be possible?
  11. The answer is simple: Two years ago, we introduced a new concept, Radical Agility. We, at Zalando, understand Radical Agility as a way of running a business based on purpose, autonomy and mastery. To describe this in one sentence would be: Trust instead of control! The final goals of Radical Agility are being represented on the edge of the slide: Increase innovation, increase productivity. What’s important for today’s talk, is that Radical Agility changed the communication structure of our tech department. We started to be organized into small, autonomous engineering teams which are trusted and accept responsibility.
  12. So here we have our first ingredient: Scaling the team! Hire diverse people, give them the freedom to self organize, give them a clear, motivating purpose, and trust that they’ll deliver great features. Reorganizing the team has consequences on the the architecture side as well:
  13. Let me introduce Conway’s Law: “organizations produce designs which are copies of their communication structures”. So as soon as a company reorganizes its team, the architecture also has to be changed. Which brings us to the next ingredient:
  14. Architecture scalability: What do we want to achieve here? We want many teams, working in parallel, at different features, without interfering with each other. Team Autonomy. We want them to deploy independently - we want to allow them to do continuous delivery, in case they want this We want programming language diversity - we want to use the right tool for the job. In our case, we used to be a java based company, now we’re putting more and more languages to production. A/B Testing: Adding and removing features really fast, drives the products forward. Experimenting with features is a great way to innovate and improve, on the product side. But wait a second, these are some of the promises microservices make on the backend.
  15. So the backend part is somehow easy, we fulfill these promises by creating backend APIs owned by teams.
  16. The questions is: do microservices solve the frontend problems we have?? Do these promises apply here as well? Let’s take a look at the traditional way of solving the frontend problem.
  17. The traditional solution, without microservices, would be to have a frontend monolith. As backend teams own APIs now, we can call those APIs from a more lightweight frontend monolith.
  18. The webapp gets contributions from multiple frontend teams.
  19. Let’s look again at some of the things we’re trying to achieve: Are the frontend teams working autonomously? No, they’re not. They still depend on each other, as they’re contributing to the same lightweight frontend monolith. Can they use and mix different tech stacks? Not really, as somebody has to choose a framework for the common frontend. Can they deploy independently, whenever they want? No, they are still bound to a release cycle. It seems that avoiding frontend microservices and solving the challenges we have, is not an option. We somehow have to make it work!
  20. Here is the Mosaic Project! Microservices for the frontend! Mosaic is a set of services and libraries, most of them open sourced, together with a specification, that defines how its components interact with each other. The goal, is to support a microservice style architecture for large scale websites. While decomposing the backend into microservices is a widely adopted approach to achieve flexibility in development and operation, most frontend solutions are still running as a monolithic application.
  21. Mosaic addresses this issue by using Fragments, services that render html that is composed together, at runtime, according to template definitions. The fragments are frontend microservices owned by different teams. Teams should be able to develop, deploy and operate these services independently of each other.
  22. What’s happening inside of a fragment? :) We can render HTML, fetch data, and we can respond to AJAX requests. Ideally there is no business logic within these fragments. None of these actions are mandatory, the ones implementing the fragment can choose. As a result, Fragments can be iterated on very rapidly, be more flexible in technology choices, and can better benefit from the extreme development pace of today's frontend technologies.
  23. As I said, in this new setup, each team owns its own fragments, they are able to choose the technology for them and can deploy them independently. Each fragment is able to do calls to different APIs. And each fragment renders a part of a final page. How does the final page get assembled from the html rendered by each of the fragments?
  24. On top of the fragments we have another service called the Layout Service. The Layout Service puts together the content rendered by fragments. It uses templates to know how to assemble them. We’ll talk about templates soon.
  25. The assembled content is streamed to the client, through a router. The router is necessary to handle API calls, mobile app calls or help in the migration from a legacy system.
  26. Let’s get from this microservices for the frontend idea, to the Mosaic implementation. We have names for both the router and the layout service. Skipper is our router and Tailor our layout service. Skipper, is a piece of software we built in house, developed as an open source project. It is the entry point for every request from the browser (excluding static resources) It acts like a reverse proxy, and will delegate the request, based on some internal routes, to one of our new microservices, or to a legacy system, like Jimmy there, in case a migration is happening
  27. It has other functions, like security features as well. For more details check out the github repository, at github.com/zalando/skipper
  28. Tailor is the Layout Service implementation, another open source project that we built. It uses streams to compose a web page from fragment services. It loads the content of all fragments from the template in parallel, offers nice error handling and fallback features.
  29. Here is how a Tailor template looks like. As you can see, most of it is html, with some special tag: Fragment. This tag acts as a placeholder, where Tailor will insert the content it gets from each specified fragment. One of the fragments has to be marked marked as primary. This is the fragment which will give the http status of the final page. You might have noticed that this concept is similar to Facebook’s BigPipe. The difference is, that with the Big Pipe, things get assembled on the client side. For SEO and user experience reasons we want most our content to be streamed in order. We can achieve a similar behavior as with the Big Pipe by using the async attribute.
  30. Let’s look at an example: We have a request for the cart page from skipper, the router. Skipper knows that the “/cart” url should be handled by Tailor, and forwards the request to it. Tailor needs the Template for the “/cart” url and in case it doesn’t have it cached, it asks Quilt, a RESTful API for it. Tailor gets the template, looks at it, and sees that it has to call the header fragment, the cart fragment and the tracking fragment. It does all of these calls in parallel, puts everything together according to the template and returns the response to skipper. The status code gets set by the cart fragment, as this is the primary fragment.
  31. A fragment may provide some JavaScript and CSS as well. Besides the static HTML, Tailor will look for additional script and stylesheet assets inside the “Link” HTTP header of the fragment response. And will inject the corresponding links in the head section of the final page.
  32. The JavaScript must be defined as an AMD (Asynchronous module definition) module that exports a single function. When finally executed on the client, this function receives the DOM element of the fragment as an argument.
  33. Because each fragment is an isolated standalone application inside the browser, fragments need a way to communicate with each other. For example, one fragment might add and article to the shopping cart. As a result of this action, another fragment wants to update the list of shopping cart items. Although there is no solution built into Mosaic itself, it is easy to add a shared communication bus that fragments can publish and subscribe to. On zalando.de we are using, the “happened” library (github.com/grassator/happened). Communication Between Fragments To facilitate communication between Fragments Mosaic suggests to use an event bus. In the Fashion Store the following approach is used. As part of the base assets an event bus based on happened is provided. Fragments that need to communicate are encouraged to register or listen to events. To that end, each fragment repository contains event definitions such that other fragment owners can figure out which events a fragment provides and listens to. Communication Between Server Side Mosaic Components It is strongly recommended to ensure that fragments handle requests only from Tailor or Skipper: oauth2 and firewalling. https://pages.github.bus.zalan.do/pathfinder/mosaic-documentation/Fragments.html?highlight=event#communication-between-fragments
  34. Here is how our Zalando cart page looks like, after it gets assembled by Tailor. The final page is assembled from 3 fragments: the header fragment, the cart fragment and another fragment that is not visible, the tracking fragment. Each of these fragments are managed by different teams.
  35. So here is our second ingredient: Scaling the architecture! Come up with an architecture which allows team autonomy, independent deployment, encourages a mix of tech stacks and experimentation.
  36. Right now, Mosaic is live, we have quite some traffic. Last year on Black Friday we had around 21 thousand requests/s on skipper and we are expecting even more this year soon, as Black Friday is about to come again.
  37. Dan: So far I have showed you how a single large website can be split into smaller fragments. Max, what’s next?? Well, as it turns out, websites are a lot more complex today than they used to be. They contain lots of interactive elements powered by JavaScript and they serve large amounts of dynamic content. Let me show you how we think we’ll manage all that!
  38. Our website, or as we call it, the Fashion Store, is actually a highly dynamic application. Here’s an example how the Fashion Store might be divided into separate fragments. Each fragment can have some sophisticated interactive behaviour and may be talking to multiple backend APIs. Naturally, we update the content on the Fashion Store very frequently with latest styles, trends and product information. The content itself is also dynamic and might change for different users because of personalization.
  39. With this is mind, what is actually the best way to implement a fragment? There are three important things that we want from our fragment: First, it must provide for our users a modern and interactive user experience similar to a web application. Second, it needs to support the dynamic and frequently updated content that we want to deliver to our customers. And lastly, the fragment has to preserve the consistent look and feel that customers have come to expect everywhere inside the Fashion Store. Given these constraints, let’s consider our implementation options, starting with the most naive approach:
  40. A very simple fragment might only render some static content. Obviously this has many drawbacks. The implementation is too manual and updating the content means changing the whole fragment and redeploying the web service. Also, the user experience is very likely going to be quite inconsistent between different independent teams.
  41. Here is another idea: instead of rendering just static HTML a fragment may react to requests dynamically, fetch some external content and send back a computed response using an HTML template engine. While this is already a lot better than the first approach, many fragments are still going to deliver inconsistent user experiences as implementations differ. The biggest drawback however is that JavaScript is not part of the fragment.
  42. So we have come up with a better concept: fragments should use existing, reusable and shared JavaScript components. Although those components run dynamically as code in the browser, they can also be readily transformed into static HTML on the server. This kind of code that allows server-side rendering is sometimes called isomorphic or universal JavaScript and many popular solutions, for example React or Vue.js, support it.
  43. Now let’s take a closer look at how this idea is supposed to work in general and how it fits together with the Mosaic architecture. Because the fragment is supposed to use only existing JavaScript components for the content of the website, we start out by describing the components that we want to use with only basic JSON.
  44. If we take React components for example, we can show that they are easily described with JSON. Every component has only three attributes: The type, which can be the name of a DOM element like “div” or “h1”. A set of properties or “props”, for example, the attributes of an HTML tag. And a list of children with more components or simply plain strings.
  45. The next step is for the fragment to take those JSON descriptions and transform them into the JavaScript and HTML that will be sent to the Tailor layout service. During this process the code from common component libraries, for example from modules on npm, can be included.
  46. So how does this code generation work? As we have seen before, React components are actually quite simple. If we know the type, properties and children, we can easily produce a hierarchy of nested function calls of the “createElement” function. Once the code is generated, we evaluate it to create a React element and then use the “renderToString” function to turn it into static HTML.
  47. The big advantage of this solution is of course that the generated JavaScript is universal, so it can run not only on the server but also on the client. So this really looks like a very promising approach...
  48. In fact, we have already implemented it and released it as an open source project. We’ve called it “Tessellate”. The project comprises two major parts that I’ll talk about in more detail next: the bundler and the renderer.
  49. In Tessellate, the process of transforming JSON into JavaScript code is performed by the bundler in four steps: First the JSON is parsed as an abstract syntax tree. Next, we use that to generate JavaScript code. In the third step, Tessellate uses webpack directly in memory to compile universal bundles from that code. Finally, those bundles are exported to a remote content delivery server for later use.
  50. Let’s inspect an example of the code that Tessellate generates. It’s actually just a single React component!
  51. The component types used in the JSON description are turned into import statements. There can be default imports and named imports. The rest of the JSON description is turned into “createElement” functions with props and children.
  52. However there is more that we can do here. Right now, all the property values are statically encoded directly inside the JSON description. But of course the root component can receive props from an outside source.
  53. So Tessellate has a way to inject external properties into the compiled React components during rendering. The values of those properties are not known ahead of time but they be can be referenced relative to the root props using JSON pointers. In addition to that, we can also bundle some properties during compilation as default values and merge them with the external properties.
  54. A common problem with React components rendered on the server is the so-called “rehydration”. We need to ensure that the same properties are used for server-side and client-side rendering. Tessellate solves this by adding an attribute to the root component that stores all the props as an inlined string. This attribute will be present inside the static HTML allowing us to retrieve the props in the browser!
  55. Finally, the generated JavaScript exports the function that the Tailor API demands. This function is going to be called on the client side inside the browser and it receives the DOM element of the fragment as an argument. This element is actually our root component. Inside the function the inlined props are extracted and the React component tree is mounted on the root element by calling the “render” function.
  56. So to summarize, the Tessellate bundler is a micro service that transforms JSON into JavaScript. The JavaScript is compiled into portable, universal UMD bundles using webpack in memory. The main bundle exports a root component and a “render” function for Tailor. The root component provides an interface to inject property values. The properties can be referenced using JSON pointers and they’re inlined as a string into HTML for rehydration. We’ll come back to this in a moment. We’ve also seen how components from external libraries can be referenced in JSON by their respective node module names and names of the exports of those modules. This was the first part of Tessellate: the bundler.
  57. The other part of Tessellate is the renderer. This is actually the fragment that renders the HTML. When this fragment receives a request, it fetches a precompiled bundle from the CDN where the bundler placed it before. Next, additional data can be loaded from external sources. Then Tessellate evaluates the code and finally renders static HTML.
  58. Here’s what the implementation of that process looks like: first the precompiled bundle is downloaded. At this point, Tessellate can use the available information in the current HTTP request to decide which bundle exactly to choose.
  59. Then the code is evaluated inside the Node JS virtual machine and the exported Root component is extracted.
  60. As we’ve seen before, this root component has an interface for external props and we can load some external data to provide those.
  61. In the final step the root component is instantiated as a React element and injected with the external props. Now the element can be rendered into HTML and sent back to the Tailor layout service.
  62. If it looks like the renderer is a lot simpler than the bundler then that’s because it is! The Tessellate fragment has only three simple jobs: download the precompiled bundle, fetch some additional external content and then render everything to HTML and send it to Tailor.
  63. This is how the complete picture looks like: we have the Tessellate bundler micro service that takes an abstract description of React components written in plain JSON. It compiles the description into universal JavaScript that can run on both the server and inside the browser. And then there is the Tessellate fragment which renders the compiled bundles and any additional external data into static HTML according to the API demanded by the Tailor layout service. This architecture meets all our requirements for the Fashion Store: With JavaScript components we can achieve a modern and interactive user experience. Content can be externalized and updated separately. And because we’re using shared component libraries, the look and feel is going to be consistent everywhere.
  64. In fact, this is was the last ingredient of our recipe: Scaling the content! We use small, reusable and shared JavaScript components to push large amounts of content. The components are consistent between many independent teams and they decouple layout and data for greater scalability.
  65. Dan: So finally, here is our recipe for scalable frontends: We have scaling the team, scaling the architecture and scaling the content as ingredients and Radical Agility, Mosaic and Tessellate as instructions.
  66. You can find more details about what we talked about on our project page, mosaic9.org. Thanks a lot for watching our presentation. Are there any questions?