#BrightonSEO	@goutaste	
Emily Grossman
MobileMoxie	
Introduc:on	to	PWAs	and	JavaScript	Frameworks
@goutaste		
hEp://www.slideshare.net/mobilemoxie
#BrightonSEO	@goutaste	
JavaScript enabled the web to create
full, interactive applications… mostly
#BrightonSEO	@goutaste	
Some of the “native app” features
were still lacking
Responsive	 Secure	 Fast	
Downloadable	 Works	Offline	 Push	No:fica:ons
#BrightonSEO	@goutaste	
Responsive	 Secure	 Fast	
Downloadable	 Works	Offline	 Push	No:fica:ons	
Progressive Web Apps (PWAs)
Change This
#BrightonSEO	@goutaste	
The App-Like Web:
Progressive Web Apps
@suzzicks	 bit.ly/cindy-mozcon-2016
#BrightonSEO	@goutaste	
Offline in
Action
#BrightonSEO	@goutaste	
PWAs = Death to the Dino
(Someone	else	made	this	illustra:on,	and	I	photographed	it.	Now	I	cannot	remember	who.	SORRY.)
#BrightonSEO	@goutaste	
Why Do People Like PWAs?
Mobile	sales	increased	by	18%	YoY	
43%	increase	in	sessions/	user	
100%	increase	in	session	dura:on	 80%	improvement	in	load	:me	
30%	higher	Conversion	Rate	than	
na:ve	app	in	Tier	3	ci:es	
20%	of	PWA	bookings	are	from	
users	who’d	uninstalled	na:ve	app	
Homepage	loads	completely	in	.8	
seconds	
Customer	acquisi:on	cost	is	10X	less	 Shoppers	spend	20%	more	?me	
than	on	previous	mobile	site	
40%	lower	bounce	rate	than	on	
previous	mobile	site	
hEps://www.pwastats.com/
#BrightonSEO	@goutaste	
THIS JUST IN
#BrightonSEO	@goutaste	
Basic
Technical
Reqs
#BrightonSEO	@goutaste	
1. App Manifest
hEp://bit.ly/webapp-manifest	
Chrome Dev ToolsViewJSON file you link to in your <head>
#BrightonSEO	@goutaste	
2. Service Worker
Web	App	 Network	
Cache	
Service	Worker	
Get	/hero.png	
I	borrowed	this	analogy	from	@jeffposnick
#BrightonSEO	@goutaste	
2. Service Worker
Web	App	 Network	
Cache	
Service	Worker	
Get	/hero.png	
I	borrowed	this	analogy	from	@jeffposnick
#BrightonSEO	@goutaste	
2. Service Worker
Web	App	 Network	
Cache	
Service	Worker	
Get	/hero.png	
I	borrowed	this	analogy	from	@jeffposnick
#BrightonSEO	@goutaste	
2. Service Worker
Web	App	 Network	
Cache	
Service	Worker	
Get	/hero.png	
I	borrowed	this	analogy	from	@jeffposnick
#BrightonSEO	@goutaste	
3. https Mobile Friendly Website
#BrightonSEO	@goutaste
#BrightonSEO	@goutaste	
You don’t need a JS framework
#BrightonSEO	@goutaste	
But many web apps are easier to build
if you do use one.
#BrightonSEO	@goutaste	
And some frameworks are easier to
make “PWA ready” than others
#BrightonSEO	@goutaste	
Meet the Vue, Preact, React
CLIs
Preact	CLI	
@addyosmani	 Watch	Addy	Intro	these:	hEps://youtu.be/aCMbSyngXB4
#BrightonSEO	@goutaste	
3 PWA Optimizations to Discuss Today:
1.	Speed	&	Performance	
2.	Measurement	
3.	Suppor7ng	Older/	Other	Browsers
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 3.	Browser	Support	
Source:	@lukew
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
@addyosmani	
“The bloat of your baseline defines how
much headroom you have for app code”
How much is taken up by your framework?
hEp://bit.ly/pwas-the-new-normal
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
@addyosmani	
“The bloat of your baseline defines how
much headroom you have for app code”
How much is taken up by your framework?
@addyosmani	 hEp://bit.ly/pwas-the-new-normal
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
@addyosmani	
How much is taken up by your framework?
@addyosmani	 hEp://bit.ly/pwas-the-new-normal
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
@addyosmani	
“The bloat of your baseline defines how
much headroom you have for app code”
How much is taken up by your framework?
@addyosmani	 hEp://bit.ly/pwas-the-new-normal
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Service
Workers
Can Speed
Up Sites
on Repeat
Views
#BrightonSEO	@goutaste	
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(
[
'/css/bootstrap.css',
'/css/main.css',
'/js/bootstrap.min.js',
'/js/jquery.min.js',
'/offline.html'
]
);
})
);
});
1.	Speed	&	Performance	
Set UpYour Service Worker to
Cache Essential Assets
On Service Worker Install Event…
hEp://bit.ly/sw-caching
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Set UpYour Service Worker to
Cache Essential Assets
document.querySelector('.cache-article').addEventListener('click', function(event) {
event.preventDefault();
var id = this.dataset.articleId;
caches.open('mysite-article-' + id).then(function(cache) {
fetch('/get-article-urls?id=' + id).then(function(response) {
// /get-article-urls returns a JSON-encoded array of
// resource URLs that a given article depends on
return response.json();
}).then(function(urls) {
cache.addAll(urls);
});
});
});
On user interaction…
(ex.“save for offline” button)
hEp://bit.ly/sw-caching
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
But That Doesn’t MeanYou Are
Done & Can Ignore Performance
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Optimize for Fast First Paint
Pre-load	is	like	saying,	“Hey,	browser!	Here’s	a	resource	you’re	going	to	need	later	on,	so	start	loading	it	now.”	
•  Pre-load can specify the download “as” =
•  "script",
•  "style",
•  "image",
•  "media",
•  "document”
bit.ly/what-is-rel-preload	
HTTP/2 + Preload = Moves the ‘start download’ time of a critical asset closer to initial request
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
bit.ly/rel-preload-demo	
VIDEO: bit.ly/rel-preload-demo
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
But I’m Doing SSR &
My First Paint Times
Are ROCKING
“ “
- Someone in the audience
#BrightonSEO	@goutaste	
One of the
Issues With
Server-Side
Rendering is
The Trade-
Off With
Time to
Interactive
Simulated	Slow	Network	hEps://youtu.be/6Ljq-Jn-EgU	
VIDEO: hEps://youtu.be/6Ljq-Jn-EgU
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
TTI has a
high
correlation
with
conversion
rates
bit.ly/google-measure-performance
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Optimize for TTI: Codesplitting
READ	THIS	TO	START:	hEps://survivejs.com/webpack/building/code-spliing/
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Subjective
Performance
How do we make waits feel faster?
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
For 2 Sec+ Waits: Progress Bars
Chris Harrison, ZhiquanYeo, Scott E. Hudson
Carnegie Mellon
hEp://www.chrisharrison.net/projects/progressbars2/ProgressBarsHarrison.pdf	
Progress bars with backwards
decelerating bands feel
12% faster
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Progress Bars
hEp://www.chrisharrison.net/projects/progressbars2/ProgressBarsHarrison.pdf
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Predictive Preloading**unfortunately a desktop-only trick
hEps://github.com/SamKnows/futurelink							hEps://github.com/SamKnows/vue-futurelink	
Optimize for Next Page Load
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
Predictive Preloading**unfortunately a desktop-only trick
hEps://blog.samknows.com/intelligent-page-preloading-with-futurelink-c1de25449dee	
VIDEO: see link below
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
“React As Soon As User Indicates Intent”
Cut Down on Click Latency
Experiment	by	Eli	Fitch:		Track	your	reac7on	7me	on	‘mousedown’	vs.	‘click	’	hNp://bit.ly/eli-fitch-fluent		
let startTime;
$('.button--onclick').on('mousedown', startTimer);
$('.button--onclick').on('click', endTimer);
function startTimer() {
startTime = Date.now();
}
function endTimer() {
const nowish = Date.now();
const timey = nowish - startTime;
$('.readout').html(`Mousedown fired <span class="bold">${timey}ms</span> before click
event`);
}
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
“React As Soon As User Indicates Intent”
Cut Down on Click Latency
“Mousedown gives you a
100 – 150ms head start”-Eli	Fitch	
hEp://bit.ly/eli-fitch-fluent
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	
“React As Soon As User Indicates Intent”
Cut Down on Click Latency
“For touch screens,
begin on touchstart &
cancel on touchmove”
-Eli	Fitch	
hEp://bit.ly/eli-fitch-fluent
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	
Measuring “Installs”
from the Chrome
PWA Install Banner
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	
Measuring “Installs”
window.addEventListener('beforeinstallprompt', function(e) {
// beforeinstallprompt Event fired
// e.userChoice will return a Promise.
// For more details read: https://developers.google.com/web/fundamentals/getting-started/primers/promises
e.userChoice.then(function(choiceResult) {
console.log(choiceResult.outcome);
if(choiceResult.outcome == 'dismissed') {
console.log('User cancelled home screen install');
}
else {
console.log('User added to home screen');
}
});
});
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	
Measuring
“Launches”
Add a tracking
parameter to your
“start_url” in the
App Manifest
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	
bit.ly/track-offline	
How Do You Record Offline “Traffic”?
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	
Measuring Push Notifications
bit.ly/GA-push-tracking
#BrightonSEO	@goutaste	
3. Supporting Old &
Other Browsers
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
What is
a
Polyfill?
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
“POLY meaning it could be solved
using any number of techniques…
and FILL would fill the hole in the
browser where the technology
needed to be.”
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
Polyfills for Other & Older
Browsers
(cough cough Chrome 41 cough cough)
“ “
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
Polyfills
for Other
& Older
Browsers
hEps://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
Polyfills
for Safari
& Older
Browsers
hEps://github.com/mathiasbynens/cache-polyfill
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
Official Safari Support is Coming “Soon”…
hEps://jakearchibald.github.io/isserviceworkerready/
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
Other Specifics for iOS
•  On iOS, Home Screen icons & splash don’t come from App Manifest
•  Specify app attributes with link tags in the <head>:
–  Icon: <link rel="apple-touch-icon" href="/custom_icon.png">
–  Launch Screen Image: <link rel="apple-touch-startup-image" href="/
launch.png">
–  App Name: <meta name="apple-mobile-web-app-title"
content="AppTitle">
–  Enable stand-alone mode: <meta name="apple-mobile-web-app-
capable" content="yes">
–  Change status bar color: <meta name="apple-mobile-web-app-status-
bar-style" content="black”>
•  There’s also a Polyfill for ^this: https://github.com/boyofgreen/manUp.js/
#BrightonSEO	@goutaste	
1.	Speed	&	Performance	 2.	Measurement	 3.	Browser	Support	
@goutaste	
#BrightonSEO
#BrightonSEO	@goutaste	
H/2 Push
Is Also
Better
With
Service
Workers
Initial Load with H/2 Push:
Repeat Load with all /push assets coming from the SW cache:
More	on	combining	H/2	Push	&	SWs:	hEps://24ways.org/2016/hEp2-server-push-and-service-workers/	
Bonus	Slide:	
starter-pack	
reading	on	H/2	
push	with		
PWAs	
More	on	H/2	Push	&	cache	management:	hEps://jakearchibald.com/2017/h2-push-tougher-than-i-thought/

Introduction to PWAs & New JS Frameworks for Mobile