SlideShare a Scribd company logo
1 of 194
Download to read offline
G O I N G W E B N AT I V E
T H E E X C I T I N G F U T U R E O F W E B
@ M A R C U S H E L L B E R G
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
FIGHT FOR SIMPLICITY
FIGHT FOR SIMPLICITY
•HOW WE GOT TO WHERE WE ARE
•WHAT THE WEB PLATFORM CAN DO TODAY
•PREDICTING THE FUTURE
T H E H I S T O R Y O F
B U I L D I N G W E B A P P L I C AT I O N S
CLIENTSERVER
Model
View
Controller
CLIENTSERVER
Model
View
Controller
CLIENTSERVER
Model
View
Controller
CLIENTSERVER
Model
View
Controller
CLIENTSERVER
Model
View
Controller
CLIENTSERVER
REST
View
Model
Controller
CLIENTSERVER
REST
View
Model
Controller
CLIENTSERVER
REST
View
Model
Controller
CLIENTSERVER
REST
View
Model
Controller
CLIENTSERVER
REST
View
Model
Controller
CLIENTSERVER
REST
Component1
Component 2
Component 4REST
REST
CLIENTSERVER
REST
Component1
Component 2
Component 4REST
REST
CLIENTSERVER
REST
Component1
Component 2
Component 4REST
REST
CLIENTSERVER
REST
Component1
Component 2
Component 4REST
REST
B U I L D I N G C O M P O N E N T S
<input type="text" id="datepicker">
STEP1:
<input type="text" id="datepicker">
STEP1:
I'm a text input!
<input type="text" id="datepicker">
STEP1:
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jq
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
STEP2:
I'm a text input!
<input type="text" id="datepicker">
STEP1:
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jq
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
STEP2:
I'm a text input!
<script>
$( function() {
$( "#datepicker" ).datepicker();
} );
</script>
STEP3:
<input type="text" id="datepicker">
STEP1:
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jq
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
STEP2:
<script>
$( function() {
$( "#datepicker" ).datepicker();
} );
</script>
STEP3:
What kind of freak am I ?!?
5 MINUTES LATER...
•Depends on a library
•JavaScript scoping issues
•CSS scoping issues
•A big bowl of spaghetti™
@Component({
selector: 'demo-component',
template: `
<h1>Hello {{user}}!</h1>
`,
styles: [`
h1 {
color: red;
}
`]
})
export class DemoComponent {
public user: String;
constructor() {
this.user = 'Marcus';
}
}
@Component({
selector: 'demo-component',
template: `
<h1>Hello {{user}}!</h1>
`,
styles: [`
h1 {
color: red;
}
`]
})
export class DemoComponent {
public user: String;
constructor() {
this.user = 'Marcus';
}
}
<demo-component>
</demo-component>
•Custom element with sensible API
•Encapsulates JavaScript and CSS
•Bound to one specific framework
•Needs to be "emulated" in the browser
P R O B L E M :
R E N D E R I S J S B L O C K E D
53% of mobile site visits are
abandoned if pages take
longer than 3 seconds to load
”
W E B C O M P O N E N T S
<web-component></web-component>
Custom Element
<web-component></web-component>
Custom Element
(needs to have a dash in the name)
<web-component></web-component>
HTML Import
<link rel="import" src="web-component.html">
<template id="web-component">
<web-component></web-component>
</template>
Template
<web-component>
# shadow root (open)
<style>
.danger { color: red; }
</style>
<span class="danger">
Alert!
</span>
</web-component>
Shadow root
B U I L D I N G A C O M P O N E N T
class CollapseLayout extends HTMLElement {
}
class CollapseLayout extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({ mode: 'open' });
}
}
class CollapseLayoutVanilla extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({ mode: 'open' });
this.root.innerHTML = `
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open]{ display: block; }
</style>
<div id="title">
<slot name="title"></slot>
</div>
<div id="content">
<slot></slot>
</div>
`;
}
}
class CollapseLayoutVanilla extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({ mode: 'open' });
this.root.innerHTML = `
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open]{ display: block; }
</style>
<div id="title">
<slot name="title"></slot>
</div>
<div id="content">
<slot></slot>
</div>
`;
}
}
class CollapseLayoutVanilla extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({ mode: 'open' });
this.root.innerHTML = `
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open]{ display: block; }
</style>
<div id="title">
<slot name="title"></slot>
</div>
<div id="content">
<slot></slot>
</div>
`;
}
}
class CollapseLayout extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({ mode: 'open' });
this.root.innerHTML = `
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open]{ display: block; }
</style>
<div id="title">
<slot name="title"></slot>
</div>
<div id="content">
<slot></slot>
</div>
`;
this.addEventListener('click', this.toggleOpen);
}
}
class CollapseLayout extends HTMLElement {
constructor() {}
toggleOpen() { this.setOpen(!this.open); }
setOpen(open) {
if (open) {
this.setAttribute('open', open);
this.root.querySelector('#content').setAttribute('open', open);
} else {
this.removeAttribute('open');
this.root.querySelector('#content').removeAttribute('open');
}
}
get open() { return this.hasAttribute('open'); }
}
class CollapseLayout extends HTMLElement {
constructor() { }
toggleOpen() { }
setOpen(open) { }
get open() { }
static get observedAttributes() { return ['open']; }
attributeChangedCallback(name, oldValue, newValue) {
if ('open' === name && this.open !== !!newValue) {
this.toggleOpen();
}
}
}
class CollapseLayout extends HTMLElement {
constructor() { }
toggleOpen() { }
setOpen(open) { }
get open() { }
static get observedAttributes() { }
attributeChangedCallback(name, oldValue, newValue) { }
}
customElements.define('collapse-layout', CollapseLayout);
<collapse-layout>
<h1 slot="title">Custom Element Title</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
elit. Ut erat nisi, placerat eget lorem a, fermentum cong
convallis mi. Mauris neque elit, pretium vitae metus sed,
ac lacinia. Phasellus lobortis vitae mauris ullamcorper p
</p>
</collapse-layout>
<collapse-layout>
<h1 slot="title">Custom Element Title</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
elit. Ut erat nisi, placerat eget lorem a, fermentum cong
convallis mi. Mauris neque elit, pretium vitae metus sed,
ac lacinia. Phasellus lobortis vitae mauris ullamcorper p
</p>
</collapse-layout>
<collapse-layout open>
<h1 slot="title">Custom Element Title</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
elit. Ut erat nisi, placerat eget lorem a, fermentum cong
convallis mi. Mauris neque elit, pretium vitae metus sed,
ac lacinia. Phasellus lobortis vitae mauris ullamcorper p
</p>
</collapse-layout>
Polymer
<dom-module id="collapse-layout">
</dom-module>
<dom-module id="collapse-layout">
<script>
class CollapseLayout extends Polymer.Element {
}
</script>
</dom-module>
<dom-module id="collapse-layout">
<script>
class CollapseLayout extends Polymer.Element {
static get is() { return 'collapse-layout'; }
}
</script>
</dom-module>
<dom-module id="collapse-layout">
<script>
class CollapseLayout extends Polymer.Element {
static get is() { return 'collapse-layout'; }
static get properties() {
return {
open: {
type: Boolean,
reflectToAttribute: true
}
}
}
}
</script>
</dom-module>
<dom-module id="collapse-layout">
<script>
class CollapseLayout extends Polymer.Element {
static get is() { return 'collapse-layout'; }
static get properties() {
return {
open: {
type: Boolean,
reflectToAttribute: true
}
}
}
toggleOpen() { this.open = !this.open; }
}
</script>
</dom-module>
<dom-module id="collapse-layout">
<script>
class CollapseLayout extends Polymer.Element {
static get is() { return 'collapse-layout'; }
static get properties() {
return {
open: {
type: Boolean,
reflectToAttribute: true
}
}
}
toggleOpen() { this.open = !this.open; }
customElements.define(CollapseLayout.is, CollapseLayout);
}
</script>
</dom-module>
<dom-module id="collapse-layout">
<template>
</template>
<script>...</script>
</dom-module>
<dom-module id="collapse-layout">
<template>
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open] { display: block; }
</style>
<div id="title">
<slot name="title" on-click="toggleOpen"></slot>
</div>
<div id="content" open$="[[open]]">
<slot></slot>
</div>
</template>
<script></script>
</dom-module>
<dom-module id="collapse-layout">
<template>
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open] { display: block; }
</style>
<div id="title">
<slot name="title" on-click="toggleOpen"></slot>
</div>
<div id="content" open$="[[open]]">
<slot></slot>
</div>
</template>
<script></script>
</dom-module>
<dom-module id="collapse-layout">
<template>
<style>
#title { cursor: pointer; }
#content { display: none; }
#content[open] { display: block; }
</style>
<div id="title">
<slot name="title" on-click="toggleOpen"></slot>
</div>
<div id="content" open$="[[open]]">
<slot></slot>
</div>
</template>
<script></script>
</dom-module>
•Simplified element creation
•Data binding
•Event handling
•Repeating and conditional templates
•CLI tool for bootstrapping and building projects
•Set of basic UI components
P O L Y M E R I S W E B C O M P O N E N T S +
vaadin.com/elements
@addyosmani
aerotwist.com/blog/when-everything-is-important-nothing-is
CLIENT SIDE RENDERING
aerotwist.com/blog/when-everything-is-important-nothing-is
SERVER SIDE RENDERING
aerotwist.com/blog/when-everything-is-important-nothing-is
PROGRESSIVE BOOTING
P R P L
P R P LP u s h
P R P LR e n d e rP u s h
P R P LP r e - c a c h eR e n d e rP u s h
P R P LP r e - c a c h eR e n d e rP u s h L a z y - l o a d
C O M P O N E N T S O N T H E W E B
A N O N - E X H A U S T I V E H I S T O R Y
C O M P O N E N T S O N T H E W E B2011
Web Components
A N O N - E X H A U S T I V E H I S T O R Y
C O M P O N E N T S O N T H E W E B2011
Web Components
2013
Polymer
React
A N O N - E X H A U S T I V E H I S T O R Y
C O M P O N E N T S O N T H E W E B2011
Web Components
2013
Polymer
React
2014
Vue
A N O N - E X H A U S T I V E H I S T O R Y
C O M P O N E N T S O N T H E W E B2011
Web Components
2013
Polymer
React
2015
Angular2
2014
Vue
A N O N - E X H A U S T I V E H I S T O R Y
C O M P O N E N T S O N T H E W E B2011
Web Components
2013
Polymer
React
2015
Angular2
2014
Vue
2016
Polymer 2
A N O N - E X H A U S T I V E H I S T O R Y
C O M P O N E N T S O N T H E W E B2011
Web Components
2013
Polymer
React
2015
Angular2
2014
Vue
2016
Polymer 2
2017
Web Components widely supported
A N O N - E X H A U S T I V E H I S T O R Y
M O B I L E
E X P E R I E N C E
Mobile now represents almost 2 out of 3
digital media minutes.
comscore.com/Insights/Presentations-and-Whitepapers/2016/The-2016-US-Mobile-App-Report
A P P I N S TA L L S / M O N T H :
A P P I N S TA L L S / M O N T H :
0
While we haven’t yet reached ‘Peak App’ the market
is definitely tightening, and app publishers need to
rethink how to break through to the consumer’s
screen.
comScore 2016 US Mobile App report
comscore.com/Insights/Presentations-and-Whitepapers/2016/The-2016-US-Mobile-App-Report
gartner.com/smarterwithgartner/gartner-predicts-2017-marketers-expect-the-unexpected
GARTNER: 20% WILL ABANDON THEIR
MOBILE APPS BY 2019
Despite significant investment and hopes for positive ROI,
mobile applications are not paying off for many
brands.
Compelling alternatives such as progressive web apps
mean the branded app economy is poised for change.
gartner.com/smarterwithgartner/gartner-predicts-2017-marketers-expect-the-unexpected
GARTNER: 20% WILL ABANDON THEIR
MOBILE APPS BY 2019
T H E P R O B L E M I S F R I C T I O N
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
open the app store80
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
open the app store80
find your app in the store64
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
open the app store80
find your app in the store64
tap install51
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
open the app store80
find your app in the store64
tap install51
accept permission requests41
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
open the app store80
find your app in the store64
tap install51
accept permission requests41
find the app on their home screen33
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
open the app store80
find your app in the store64
tap install51
accept permission requests41
find the app on their home screen33
26 will open the app
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
tap install80
accept permission requests64
find the app on their home screen51
41will open the app
S T I L L , O N L Y . . .
C O S T P E R I N S TA L L
$ 1 . 5 0 +
fiksu.com/resources/fiksu-indexes
Users spend almost
90% of time in their top
5 apps.
Source: comScore 2016 report
W H AT A B O U T M O B I L E W E B ?
80 will open the app
O U T O F 1 0 0 I N T E R E S T E D P E O P L E
Source: comScore 2016 report
0
3
6
9
12
# Visitors (MM)
Native apps Mobile web
Top 1000 Mobile Apps vs. Top 1000 Mobile Web Properties
Source: comScore 2016 report
0
3
6
9
12
# Visitors (MM)
3x
Native apps Mobile web
Top 1000 Mobile Apps vs. Top 1000 Mobile Web Properties
Source: comScore 2016 report
0
3
6
9
12
# Visitors (MM)
0
50
100
150
200
Minutes
3x 20x
Native apps Mobile web
Top 1000 Mobile Apps vs. Top 1000 Mobile Web Properties
WHAT'S HOLDING BACK THE
MOBILE WEB?
1 . B A D U S E R E X P E R I E N C E
2 . P O O R R E - E N G A G E M E N T
Your t-shirt order has shipped. Track it here.
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
Vaadin Store
3 . P E R F O R M A N C E
P R O G R E S S I V E W E B A P P S
1. Reliable
1. Reliable
2. Fast
1. Reliable
2. Fast
3. Engaging
T R Y B E F O R E Y O U B U Y
P W A C H E C K L I S T :
Responsive layouts, works on mobile
Site works cross-browser
Page transitions don't feel like they block on network
Each page has a URL
developers.google.com/web/progressive-web-apps/checklist
P W A C H E C K L I S T :
Site is served over HTTPS
Responsive layouts, works on mobile
Site works cross-browser
Page transitions don't feel like they block on network
Each page has a URL
developers.google.com/web/progressive-web-apps/checklist
P W A C H E C K L I S T :
Site is served over HTTPS
Responsive layouts, works on mobile
Site works cross-browser
Page transitions don't feel like they block on network
Each page has a URL
Metadata is provided for Add to Home screen
developers.google.com/web/progressive-web-apps/checklist
P W A C H E C K L I S T :
Site is served over HTTPS
Responsive layouts, works on mobile
First load is fast even on 3G
Site works cross-browser
Page transitions don't feel like they block on network
Each page has a URL
Metadata is provided for Add to Home screen
developers.google.com/web/progressive-web-apps/checklist
D O Y O U N E E D T O S TA R T F R O M
S C R AT C H ?
D O Y O U N E E D T O S TA R T F R O M
S C R AT C H ?
N O .
1 . A D D A N A P P M A N I F E S T
{
"name": "Todo App",
"icons": [{
"src": "todo.png",
"sizes": "192x192",
"type": "image/png"
}],
"start_url": "/index.html",
"display": "standalone",
"orientation": "portrait"
}
https://developer.mozilla.org/en-US/docs/Web/Manifest
W E B A P P M A N I F E S T
<head>
...
<link rel="manifest" href="/manifest.webmanifest">
</head>
2 . D E F I N E A S E R V I C E W O R K E R
Service worker

S E R V I C E W O R K E R
if ('serviceWorker' in navigator) {
}
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js');
});
}
let CACHE_NAME = 'cache-v1';
let urlsToCache = ['/', '/styles/main.css',
'/script/main.js'];
/sw.js
let CACHE_NAME = 'cache-v1';
let urlsToCache = ['/', '/styles/main.css',
'/script/main.js'];
self.addEventListener('install', event => {
});
let CACHE_NAME = 'cache-v1';
let urlsToCache = ['/', '/styles/main.css',
'/script/main.js'];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME));
});
let CACHE_NAME = 'cache-v1';
let urlsToCache = ['/', '/styles/main.css',
'/script/main.js'];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache));
);
});
self.addEventListener('fetch', event => {
});
self.addEventListener('fetch', event => {
event.respondWith(
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
github.com/GoogleChrome/sw-toolbox
T O O L S
github.com/GoogleChrome/sw-toolbox
toolbox.router.get('*.json', toolbox.cacheFirst);->
T O O L S
github.com/GoogleChrome/sw-precache
github.com/GoogleChrome/sw-toolbox
toolbox.router.get('*.json', toolbox.cacheFirst);->
T O O L S
3 . A D D P U S H , B A C K G R O U N D S Y N C
( I F Y O U W A N T T O )
developers.google.com/web/fundamentals/
getting-started/codelabs/push-notifications
You can progressively enhance your existing app
to become a Progressive Web App.
Taking an app designed for desktop and slapping
on a ServiceWorker won't make it a PWA.
Lighthouse
T H E B A D N E W S
N O I O S S U P P O R T
N O I O S S U P P O R T
(YET)
T H E G O O D N E W S
G R E AT A N D R O I D S U P P O R T
G R E AT A N D R O I D S U P P O R T
(88% MARKET SHARE)
A N D D E S K T O P
T H E Y A R E A P R O G R E S S I V E
E N H A N C E M E N T
C A N B E U S E D W I T H A N Y
F R A M E W O R K
P A R T O F T H E W E B P L AT F O R M
W H AT ' S A H E A D ?
THE WEB IS THE NEXT BIG
PLATFORM FOR APPS
HARDWARE ACCESS
A SAMPLE OF INTERESTING WEB SPECS
Web Bluetooth
Device motion
Ambient light sensor
Vibration
BROWSER
Background sync
Payment API
Share API
Credentials API
Persistent storage
GAMING
Web Assembly
WebGL
WebVR
NATIVE ISN'T GOING AWAY
NATIVE ISN'T GOING AWAY
BUT IT WILL BECOME MORE NICHE
medium.com/@owencm/reactive-web-design-the-secret-
to-building-web-apps-that-feel-amazing-b5cbfe9b7c50
BORROWING IDEAS
FRAMEWORKS WILL BECOME LIGHTER AND
MORE MODULAR
PHYSICAL WEB WILL MEAN MORE
SINGLE-USE APPS
Reaching the next generation of web users will
require performance and bandwidth consciousness
Reaching the next generation of web users will
require performance and bandwidth consciousness
Native Lite
Example:
INDIA
Reaching the next generation of web users will
require performance and bandwidth consciousness
216MB/month
Native Lite
Example:
INDIA
Reaching the next generation of web users will
require performance and bandwidth consciousness
8.6MB/month216MB/month
Native Lite
Example:
INDIA
Reaching the next generation of web users will
require performance and bandwidth consciousness
8.6MB/month216MB/month
= 7.3h work
Native Lite
Example:
INDIA
Reaching the next generation of web users will
require performance and bandwidth consciousness
8.6MB/month216MB/month
= 7.3h work = 0.5h work
Native Lite
Example:
INDIA
Data sync is the next JS framework war
– Alex Russell”
F U R T H E R R E A D I N G
aerotwist.com/blog/the-cost-of-frameworks
aerotwist.com/blog/when-everything-is-important-nothing-is
medium.com/@marcushellberg/simplifying-performance-with-web-components-7d5327314b69
infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul
developers.google.com/web/fundamentals
P E O P L E T O F O L L O W
( O N S O C I A L M E D I A , Y O U C R E E P )
@slightlylate
Alex Russell
@aerotwist
Paul Lewis
@nolanlawson
Nolan Lawson
@jaffathecake
Jake Archibald
@owencrm
Owen Campbell-Moore
I’ve found it’s been a better long-term
investment for me to learn the Web Platform
than any particular library, framework or tool
– Paul Lewis
”
D I S C U S S I O N
T H A N K Y O U !
@ M A R C U S H E L L B E R G
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N

More Related Content

Similar to Going web native

Vaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UIVaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UIPeter Lehto
 
Going web native - Feb 2018
Going web native - Feb 2018Going web native - Feb 2018
Going web native - Feb 2018Marcus Hellberg
 
Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018Peter Lehto
 
Building web apps with Vaadin 8
Building web apps with Vaadin 8 Building web apps with Vaadin 8
Building web apps with Vaadin 8 Marcus Hellberg
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.UA Mobile
 
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpOptimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpMatthew Davis
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSMartin Hochel
 
Course CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.jsCourse CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.jsVinícius de Moraes
 
Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017Matt Raible
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile wayAshwin Raghav
 
243329387 angular-docs
243329387 angular-docs243329387 angular-docs
243329387 angular-docsAbhi166803
 
Web Development for UX Designers
Web Development for UX DesignersWeb Development for UX Designers
Web Development for UX DesignersAshlimarie
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletonGeorge Nguyen
 
Developing for LinkedIn's Application Platform
Developing for LinkedIn's Application PlatformDeveloping for LinkedIn's Application Platform
Developing for LinkedIn's Application PlatformTaylor Singletary
 
Pwa, separating the features from the solutions
Pwa, separating the features from the solutions Pwa, separating the features from the solutions
Pwa, separating the features from the solutions Sander Mangel
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSmurtazahaveliwala
 
Embedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStart
Embedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStartEmbedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStart
Embedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStartScott DeLoach
 
The State of Front-end At CrowdTwist
The State of Front-end At CrowdTwistThe State of Front-end At CrowdTwist
The State of Front-end At CrowdTwistMark Fayngersh
 

Similar to Going web native (20)

Vaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UIVaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UI
 
Going web native - Feb 2018
Going web native - Feb 2018Going web native - Feb 2018
Going web native - Feb 2018
 
Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018
 
Building web apps with Vaadin 8
Building web apps with Vaadin 8 Building web apps with Vaadin 8
Building web apps with Vaadin 8
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.
 
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and GulpOptimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJS
 
Course CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.jsCourse CodeSchool - Shaping up with Angular.js
Course CodeSchool - Shaping up with Angular.js
 
Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile way
 
243329387 angular-docs
243329387 angular-docs243329387 angular-docs
243329387 angular-docs
 
Web Development for UX Designers
Web Development for UX DesignersWeb Development for UX Designers
Web Development for UX Designers
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
 
Developing for LinkedIn's Application Platform
Developing for LinkedIn's Application PlatformDeveloping for LinkedIn's Application Platform
Developing for LinkedIn's Application Platform
 
Pwa, separating the features from the solutions
Pwa, separating the features from the solutions Pwa, separating the features from the solutions
Pwa, separating the features from the solutions
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
 
Embedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStart
Embedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStartEmbedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStart
Embedded UA 101 - STC Summit 2013, Scott DeLoach, ClickStart
 
Building Web Hack Interfaces
Building Web Hack InterfacesBuilding Web Hack Interfaces
Building Web Hack Interfaces
 
The State of Front-end At CrowdTwist
The State of Front-end At CrowdTwistThe State of Front-end At CrowdTwist
The State of Front-end At CrowdTwist
 

More from Marcus Hellberg

Building performant web apps
Building performant web appsBuilding performant web apps
Building performant web appsMarcus Hellberg
 
Building web apps with vaadin 10
Building web apps with vaadin 10Building web apps with vaadin 10
Building web apps with vaadin 10Marcus Hellberg
 
Progressive web apps with polymer
Progressive web apps with polymerProgressive web apps with polymer
Progressive web apps with polymerMarcus Hellberg
 

More from Marcus Hellberg (6)

Building performant web apps
Building performant web appsBuilding performant web apps
Building performant web apps
 
Building web apps with vaadin 10
Building web apps with vaadin 10Building web apps with vaadin 10
Building web apps with vaadin 10
 
Progressive web apps with polymer
Progressive web apps with polymerProgressive web apps with polymer
Progressive web apps with polymer
 
Booting up with polymer
Booting up with polymerBooting up with polymer
Booting up with polymer
 
Booting up with polymer
Booting up with polymerBooting up with polymer
Booting up with polymer
 
Vaadin NYC Meetup
Vaadin NYC MeetupVaadin NYC Meetup
Vaadin NYC Meetup
 

Recently uploaded

What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfIdiosysTechnologies1
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 

Recently uploaded (20)

What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdf
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 

Going web native

  • 1. G O I N G W E B N AT I V E T H E E X C I T I N G F U T U R E O F W E B @ M A R C U S H E L L B E R G 5 S T O R Y A N D P H I L O S O P H Y Software is eating the world and what most of us see of it is the user interface. The user interface has become the key component of how the users experience the business behind it. Competition is lost or won due to user experience. Simplicity is king and the users get frustrated by anything ugly, slow or not working on the device they happen to use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight. Together we want to build a user interface that puts a smile on the user’s face. Vaadin is the technology that empowers developers to build the best web-apps for business purposes. Our priority over everything else is developer productivity because we believe that by simplifying the developer experience and saving the developer’s time, they are best able to focus on building great user interfaces. Our brand is what we want everyone to think about us. When everyone - both us and the people around us - have a consistent understanding of what Vaadin is and what we stand for, it enables that image to spread and amplify. This book defines what we want that image to be. It defines what the Vaadin brand is. I hope that You are as excited and proud of living and breathing the Vaadin brand as I am. You are the one who is shaping what everyone thinks about Vaadin - using this brand as a tool and a guideline every day. Let’s fight for simplicity for both the users and the developers! Joonas Lehtinen Founder & CEO Vaadin I N T R O D U C T I O N
  • 2.
  • 3.
  • 6.
  • 7. •HOW WE GOT TO WHERE WE ARE •WHAT THE WEB PLATFORM CAN DO TODAY •PREDICTING THE FUTURE
  • 8. T H E H I S T O R Y O F B U I L D I N G W E B A P P L I C AT I O N S
  • 23. B U I L D I N G C O M P O N E N T S
  • 26. <input type="text" id="datepicker"> STEP1: <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jq <link rel="stylesheet" href="/resources/demos/style.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> STEP2: I'm a text input!
  • 27. <input type="text" id="datepicker"> STEP1: <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jq <link rel="stylesheet" href="/resources/demos/style.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> STEP2: I'm a text input! <script> $( function() { $( "#datepicker" ).datepicker(); } ); </script> STEP3:
  • 28. <input type="text" id="datepicker"> STEP1: <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jq <link rel="stylesheet" href="/resources/demos/style.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> STEP2: <script> $( function() { $( "#datepicker" ).datepicker(); } ); </script> STEP3: What kind of freak am I ?!?
  • 30.
  • 31. •Depends on a library •JavaScript scoping issues •CSS scoping issues •A big bowl of spaghetti™
  • 32.
  • 33. @Component({ selector: 'demo-component', template: ` <h1>Hello {{user}}!</h1> `, styles: [` h1 { color: red; } `] }) export class DemoComponent { public user: String; constructor() { this.user = 'Marcus'; } }
  • 34. @Component({ selector: 'demo-component', template: ` <h1>Hello {{user}}!</h1> `, styles: [` h1 { color: red; } `] }) export class DemoComponent { public user: String; constructor() { this.user = 'Marcus'; } } <demo-component> </demo-component>
  • 35. •Custom element with sensible API •Encapsulates JavaScript and CSS •Bound to one specific framework •Needs to be "emulated" in the browser
  • 36. P R O B L E M : R E N D E R I S J S B L O C K E D
  • 37.
  • 38. 53% of mobile site visits are abandoned if pages take longer than 3 seconds to load ”
  • 39. W E B C O M P O N E N T S
  • 44. <web-component> # shadow root (open) <style> .danger { color: red; } </style> <span class="danger"> Alert! </span> </web-component> Shadow root
  • 45. B U I L D I N G A C O M P O N E N T
  • 46.
  • 47.
  • 48. class CollapseLayout extends HTMLElement { }
  • 49. class CollapseLayout extends HTMLElement { constructor() { super(); this.root = this.attachShadow({ mode: 'open' }); } }
  • 50. class CollapseLayoutVanilla extends HTMLElement { constructor() { super(); this.root = this.attachShadow({ mode: 'open' }); this.root.innerHTML = ` <style> #title { cursor: pointer; } #content { display: none; } #content[open]{ display: block; } </style> <div id="title"> <slot name="title"></slot> </div> <div id="content"> <slot></slot> </div> `; } }
  • 51. class CollapseLayoutVanilla extends HTMLElement { constructor() { super(); this.root = this.attachShadow({ mode: 'open' }); this.root.innerHTML = ` <style> #title { cursor: pointer; } #content { display: none; } #content[open]{ display: block; } </style> <div id="title"> <slot name="title"></slot> </div> <div id="content"> <slot></slot> </div> `; } }
  • 52. class CollapseLayoutVanilla extends HTMLElement { constructor() { super(); this.root = this.attachShadow({ mode: 'open' }); this.root.innerHTML = ` <style> #title { cursor: pointer; } #content { display: none; } #content[open]{ display: block; } </style> <div id="title"> <slot name="title"></slot> </div> <div id="content"> <slot></slot> </div> `; } }
  • 53. class CollapseLayout extends HTMLElement { constructor() { super(); this.root = this.attachShadow({ mode: 'open' }); this.root.innerHTML = ` <style> #title { cursor: pointer; } #content { display: none; } #content[open]{ display: block; } </style> <div id="title"> <slot name="title"></slot> </div> <div id="content"> <slot></slot> </div> `; this.addEventListener('click', this.toggleOpen); } }
  • 54. class CollapseLayout extends HTMLElement { constructor() {} toggleOpen() { this.setOpen(!this.open); } setOpen(open) { if (open) { this.setAttribute('open', open); this.root.querySelector('#content').setAttribute('open', open); } else { this.removeAttribute('open'); this.root.querySelector('#content').removeAttribute('open'); } } get open() { return this.hasAttribute('open'); } }
  • 55. class CollapseLayout extends HTMLElement { constructor() { } toggleOpen() { } setOpen(open) { } get open() { } static get observedAttributes() { return ['open']; } attributeChangedCallback(name, oldValue, newValue) { if ('open' === name && this.open !== !!newValue) { this.toggleOpen(); } } }
  • 56. class CollapseLayout extends HTMLElement { constructor() { } toggleOpen() { } setOpen(open) { } get open() { } static get observedAttributes() { } attributeChangedCallback(name, oldValue, newValue) { } } customElements.define('collapse-layout', CollapseLayout);
  • 57. <collapse-layout> <h1 slot="title">Custom Element Title</h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. elit. Ut erat nisi, placerat eget lorem a, fermentum cong convallis mi. Mauris neque elit, pretium vitae metus sed, ac lacinia. Phasellus lobortis vitae mauris ullamcorper p </p> </collapse-layout>
  • 58. <collapse-layout> <h1 slot="title">Custom Element Title</h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. elit. Ut erat nisi, placerat eget lorem a, fermentum cong convallis mi. Mauris neque elit, pretium vitae metus sed, ac lacinia. Phasellus lobortis vitae mauris ullamcorper p </p> </collapse-layout>
  • 59. <collapse-layout open> <h1 slot="title">Custom Element Title</h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. elit. Ut erat nisi, placerat eget lorem a, fermentum cong convallis mi. Mauris neque elit, pretium vitae metus sed, ac lacinia. Phasellus lobortis vitae mauris ullamcorper p </p> </collapse-layout>
  • 62. <dom-module id="collapse-layout"> <script> class CollapseLayout extends Polymer.Element { } </script> </dom-module>
  • 63. <dom-module id="collapse-layout"> <script> class CollapseLayout extends Polymer.Element { static get is() { return 'collapse-layout'; } } </script> </dom-module>
  • 64. <dom-module id="collapse-layout"> <script> class CollapseLayout extends Polymer.Element { static get is() { return 'collapse-layout'; } static get properties() { return { open: { type: Boolean, reflectToAttribute: true } } } } </script> </dom-module>
  • 65. <dom-module id="collapse-layout"> <script> class CollapseLayout extends Polymer.Element { static get is() { return 'collapse-layout'; } static get properties() { return { open: { type: Boolean, reflectToAttribute: true } } } toggleOpen() { this.open = !this.open; } } </script> </dom-module>
  • 66. <dom-module id="collapse-layout"> <script> class CollapseLayout extends Polymer.Element { static get is() { return 'collapse-layout'; } static get properties() { return { open: { type: Boolean, reflectToAttribute: true } } } toggleOpen() { this.open = !this.open; } customElements.define(CollapseLayout.is, CollapseLayout); } </script> </dom-module>
  • 68. <dom-module id="collapse-layout"> <template> <style> #title { cursor: pointer; } #content { display: none; } #content[open] { display: block; } </style> <div id="title"> <slot name="title" on-click="toggleOpen"></slot> </div> <div id="content" open$="[[open]]"> <slot></slot> </div> </template> <script></script> </dom-module>
  • 69. <dom-module id="collapse-layout"> <template> <style> #title { cursor: pointer; } #content { display: none; } #content[open] { display: block; } </style> <div id="title"> <slot name="title" on-click="toggleOpen"></slot> </div> <div id="content" open$="[[open]]"> <slot></slot> </div> </template> <script></script> </dom-module>
  • 70. <dom-module id="collapse-layout"> <template> <style> #title { cursor: pointer; } #content { display: none; } #content[open] { display: block; } </style> <div id="title"> <slot name="title" on-click="toggleOpen"></slot> </div> <div id="content" open$="[[open]]"> <slot></slot> </div> </template> <script></script> </dom-module>
  • 71. •Simplified element creation •Data binding •Event handling •Repeating and conditional templates •CLI tool for bootstrapping and building projects •Set of basic UI components P O L Y M E R I S W E B C O M P O N E N T S +
  • 72.
  • 74.
  • 75.
  • 80. P R P L
  • 81. P R P LP u s h
  • 82. P R P LR e n d e rP u s h
  • 83. P R P LP r e - c a c h eR e n d e rP u s h
  • 84. P R P LP r e - c a c h eR e n d e rP u s h L a z y - l o a d
  • 85. C O M P O N E N T S O N T H E W E B A N O N - E X H A U S T I V E H I S T O R Y
  • 86. C O M P O N E N T S O N T H E W E B2011 Web Components A N O N - E X H A U S T I V E H I S T O R Y
  • 87. C O M P O N E N T S O N T H E W E B2011 Web Components 2013 Polymer React A N O N - E X H A U S T I V E H I S T O R Y
  • 88. C O M P O N E N T S O N T H E W E B2011 Web Components 2013 Polymer React 2014 Vue A N O N - E X H A U S T I V E H I S T O R Y
  • 89. C O M P O N E N T S O N T H E W E B2011 Web Components 2013 Polymer React 2015 Angular2 2014 Vue A N O N - E X H A U S T I V E H I S T O R Y
  • 90. C O M P O N E N T S O N T H E W E B2011 Web Components 2013 Polymer React 2015 Angular2 2014 Vue 2016 Polymer 2 A N O N - E X H A U S T I V E H I S T O R Y
  • 91. C O M P O N E N T S O N T H E W E B2011 Web Components 2013 Polymer React 2015 Angular2 2014 Vue 2016 Polymer 2 2017 Web Components widely supported A N O N - E X H A U S T I V E H I S T O R Y
  • 92. M O B I L E E X P E R I E N C E
  • 93. Mobile now represents almost 2 out of 3 digital media minutes. comscore.com/Insights/Presentations-and-Whitepapers/2016/The-2016-US-Mobile-App-Report
  • 94.
  • 95. A P P I N S TA L L S / M O N T H :
  • 96. A P P I N S TA L L S / M O N T H : 0
  • 97. While we haven’t yet reached ‘Peak App’ the market is definitely tightening, and app publishers need to rethink how to break through to the consumer’s screen. comScore 2016 US Mobile App report comscore.com/Insights/Presentations-and-Whitepapers/2016/The-2016-US-Mobile-App-Report
  • 99. Despite significant investment and hopes for positive ROI, mobile applications are not paying off for many brands. Compelling alternatives such as progressive web apps mean the branded app economy is poised for change. gartner.com/smarterwithgartner/gartner-predicts-2017-marketers-expect-the-unexpected GARTNER: 20% WILL ABANDON THEIR MOBILE APPS BY 2019
  • 100. T H E P R O B L E M I S F R I C T I O N
  • 101. O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 102. open the app store80 O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 103. open the app store80 find your app in the store64 O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 104. open the app store80 find your app in the store64 tap install51 O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 105. open the app store80 find your app in the store64 tap install51 accept permission requests41 O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 106. open the app store80 find your app in the store64 tap install51 accept permission requests41 find the app on their home screen33 O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 107. open the app store80 find your app in the store64 tap install51 accept permission requests41 find the app on their home screen33 26 will open the app O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 108.
  • 109. tap install80 accept permission requests64 find the app on their home screen51 41will open the app S T I L L , O N L Y . . .
  • 110. C O S T P E R I N S TA L L $ 1 . 5 0 + fiksu.com/resources/fiksu-indexes
  • 111. Users spend almost 90% of time in their top 5 apps. Source: comScore 2016 report
  • 112. W H AT A B O U T M O B I L E W E B ?
  • 113.
  • 114. 80 will open the app O U T O F 1 0 0 I N T E R E S T E D P E O P L E
  • 115. Source: comScore 2016 report 0 3 6 9 12 # Visitors (MM) Native apps Mobile web Top 1000 Mobile Apps vs. Top 1000 Mobile Web Properties
  • 116. Source: comScore 2016 report 0 3 6 9 12 # Visitors (MM) 3x Native apps Mobile web Top 1000 Mobile Apps vs. Top 1000 Mobile Web Properties
  • 117. Source: comScore 2016 report 0 3 6 9 12 # Visitors (MM) 0 50 100 150 200 Minutes 3x 20x Native apps Mobile web Top 1000 Mobile Apps vs. Top 1000 Mobile Web Properties
  • 118. WHAT'S HOLDING BACK THE MOBILE WEB?
  • 119. 1 . B A D U S E R E X P E R I E N C E
  • 120.
  • 121.
  • 122.
  • 123. 2 . P O O R R E - E N G A G E M E N T
  • 124.
  • 125.
  • 126. Your t-shirt order has shipped. Track it here. 5 S T O R Y A N D P H I L O S O P H Y Software is eating the world and what most of us see of it is the user interface. The user interface has become the key component of how the users experience the business behind it. Competition is lost or won due to user experience. Simplicity is king and the users get frustrated by anything ugly, slow or not working on the device they happen to use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight. Together we want to build a user interface that puts a smile on the user’s face. Vaadin is the technology that empowers developers to build the best web-apps for business purposes. Our priority over everything else is developer productivity because we believe that by simplifying the developer experience and saving the developer’s time, they are best able to focus on building great user interfaces. Our brand is what we want everyone to think about us. When everyone - both us and the people around us - have a consistent understanding of what Vaadin is and what we stand for, it enables that image to spread and amplify. This book defines what we want that image to be. It defines what the Vaadin brand is. I hope that You are as excited and proud of living and breathing the Vaadin brand as I am. You are the one who is shaping what everyone thinks about Vaadin - using this brand as a tool and a guideline every day. Let’s fight for simplicity for both the users and the developers! Joonas Lehtinen Founder & CEO Vaadin I N T R O D U C T I O N Vaadin Store
  • 127. 3 . P E R F O R M A N C E
  • 128. P R O G R E S S I V E W E B A P P S
  • 132. T R Y B E F O R E Y O U B U Y
  • 133.
  • 134.
  • 135.
  • 136.
  • 137. P W A C H E C K L I S T : Responsive layouts, works on mobile Site works cross-browser Page transitions don't feel like they block on network Each page has a URL developers.google.com/web/progressive-web-apps/checklist
  • 138. P W A C H E C K L I S T : Site is served over HTTPS Responsive layouts, works on mobile Site works cross-browser Page transitions don't feel like they block on network Each page has a URL developers.google.com/web/progressive-web-apps/checklist
  • 139. P W A C H E C K L I S T : Site is served over HTTPS Responsive layouts, works on mobile Site works cross-browser Page transitions don't feel like they block on network Each page has a URL Metadata is provided for Add to Home screen developers.google.com/web/progressive-web-apps/checklist
  • 140. P W A C H E C K L I S T : Site is served over HTTPS Responsive layouts, works on mobile First load is fast even on 3G Site works cross-browser Page transitions don't feel like they block on network Each page has a URL Metadata is provided for Add to Home screen developers.google.com/web/progressive-web-apps/checklist
  • 141. D O Y O U N E E D T O S TA R T F R O M S C R AT C H ?
  • 142. D O Y O U N E E D T O S TA R T F R O M S C R AT C H ? N O .
  • 143. 1 . A D D A N A P P M A N I F E S T
  • 144. { "name": "Todo App", "icons": [{ "src": "todo.png", "sizes": "192x192", "type": "image/png" }], "start_url": "/index.html", "display": "standalone", "orientation": "portrait" } https://developer.mozilla.org/en-US/docs/Web/Manifest W E B A P P M A N I F E S T
  • 146. 2 . D E F I N E A S E R V I C E W O R K E R
  • 147. Service worker  S E R V I C E W O R K E R
  • 148. if ('serviceWorker' in navigator) { }
  • 149. if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js'); }); }
  • 150. let CACHE_NAME = 'cache-v1'; let urlsToCache = ['/', '/styles/main.css', '/script/main.js']; /sw.js
  • 151. let CACHE_NAME = 'cache-v1'; let urlsToCache = ['/', '/styles/main.css', '/script/main.js']; self.addEventListener('install', event => { });
  • 152. let CACHE_NAME = 'cache-v1'; let urlsToCache = ['/', '/styles/main.css', '/script/main.js']; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME)); });
  • 153. let CACHE_NAME = 'cache-v1'; let urlsToCache = ['/', '/styles/main.css', '/script/main.js']; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => cache.addAll(urlsToCache)); ); });
  • 155. self.addEventListener('fetch', event => { event.respondWith( ); });
  • 156. self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request) ); });
  • 157. self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request) .then(response => { if (response) { return response; } return fetch(event.request); } ) ); });
  • 161. 3 . A D D P U S H , B A C K G R O U N D S Y N C ( I F Y O U W A N T T O )
  • 163. You can progressively enhance your existing app to become a Progressive Web App. Taking an app designed for desktop and slapping on a ServiceWorker won't make it a PWA.
  • 165. T H E B A D N E W S
  • 166. N O I O S S U P P O R T
  • 167. N O I O S S U P P O R T (YET)
  • 168. T H E G O O D N E W S
  • 169. G R E AT A N D R O I D S U P P O R T
  • 170. G R E AT A N D R O I D S U P P O R T (88% MARKET SHARE)
  • 171. A N D D E S K T O P
  • 172. T H E Y A R E A P R O G R E S S I V E E N H A N C E M E N T
  • 173. C A N B E U S E D W I T H A N Y F R A M E W O R K P A R T O F T H E W E B P L AT F O R M
  • 174.
  • 175. W H AT ' S A H E A D ?
  • 176. THE WEB IS THE NEXT BIG PLATFORM FOR APPS
  • 177. HARDWARE ACCESS A SAMPLE OF INTERESTING WEB SPECS Web Bluetooth Device motion Ambient light sensor Vibration BROWSER Background sync Payment API Share API Credentials API Persistent storage GAMING Web Assembly WebGL WebVR
  • 179. NATIVE ISN'T GOING AWAY BUT IT WILL BECOME MORE NICHE
  • 181. FRAMEWORKS WILL BECOME LIGHTER AND MORE MODULAR
  • 182. PHYSICAL WEB WILL MEAN MORE SINGLE-USE APPS
  • 183. Reaching the next generation of web users will require performance and bandwidth consciousness
  • 184. Reaching the next generation of web users will require performance and bandwidth consciousness Native Lite Example: INDIA
  • 185. Reaching the next generation of web users will require performance and bandwidth consciousness 216MB/month Native Lite Example: INDIA
  • 186. Reaching the next generation of web users will require performance and bandwidth consciousness 8.6MB/month216MB/month Native Lite Example: INDIA
  • 187. Reaching the next generation of web users will require performance and bandwidth consciousness 8.6MB/month216MB/month = 7.3h work Native Lite Example: INDIA
  • 188. Reaching the next generation of web users will require performance and bandwidth consciousness 8.6MB/month216MB/month = 7.3h work = 0.5h work Native Lite Example: INDIA
  • 189. Data sync is the next JS framework war – Alex Russell”
  • 190. F U R T H E R R E A D I N G aerotwist.com/blog/the-cost-of-frameworks aerotwist.com/blog/when-everything-is-important-nothing-is medium.com/@marcushellberg/simplifying-performance-with-web-components-7d5327314b69 infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul developers.google.com/web/fundamentals
  • 191. P E O P L E T O F O L L O W ( O N S O C I A L M E D I A , Y O U C R E E P ) @slightlylate Alex Russell @aerotwist Paul Lewis @nolanlawson Nolan Lawson @jaffathecake Jake Archibald @owencrm Owen Campbell-Moore
  • 192. I’ve found it’s been a better long-term investment for me to learn the Web Platform than any particular library, framework or tool – Paul Lewis ”
  • 193. D I S C U S S I O N
  • 194. T H A N K Y O U ! @ M A R C U S H E L L B E R G 5 S T O R Y A N D P H I L O S O P H Y Software is eating the world and what most of us see of it is the user interface. The user interface has become the key component of how the users experience the business behind it. Competition is lost or won due to user experience. Simplicity is king and the users get frustrated by anything ugly, slow or not working on the device they happen to use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight. Together we want to build a user interface that puts a smile on the user’s face. Vaadin is the technology that empowers developers to build the best web-apps for business purposes. Our priority over everything else is developer productivity because we believe that by simplifying the developer experience and saving the developer’s time, they are best able to focus on building great user interfaces. Our brand is what we want everyone to think about us. When everyone - both us and the people around us - have a consistent understanding of what Vaadin is and what we stand for, it enables that image to spread and amplify. This book defines what we want that image to be. It defines what the Vaadin brand is. I hope that You are as excited and proud of living and breathing the Vaadin brand as I am. You are the one who is shaping what everyone thinks about Vaadin - using this brand as a tool and a guideline every day. Let’s fight for simplicity for both the users and the developers! Joonas Lehtinen Founder & CEO Vaadin I N T R O D U C T I O N