Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Progressive Web Apps - fullStackTO/FITC Web Unl...
Search
Houssein Djirdeh
September 26, 2017
230
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Progressive Web Apps - fullStackTO/FITC Web Unleashed
Houssein Djirdeh
September 26, 2017
More Decks by Houssein Djirdeh
See All by Houssein Djirdeh
Performance Empathy
housseindjirdeh
0
210
The Art of Lazy Loading
housseindjirdeh
0
580
GitPoint - Lunch and Learn
housseindjirdeh
0
130
Once you go PRPL - FullStackFest
housseindjirdeh
0
46
Once you go PRPL: SeattleJS
housseindjirdeh
0
200
Featured
See All Featured
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Test your architecture with Archunit
thirion
1
2.3k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
370
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
150
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
WENDY [Excerpt]
tessaabrams
11
38k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Designing for Performance
lara
611
70k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
520
Code Reviewing Like a Champion
maltzj
528
40k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
440
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Transcript
PROGRESSIVE WEB APPLICATIONS @hdjirdeh
None
None
WEBPAGE INGREDIENT INGREDIENT INGREDIENT INGREDIENT INGREDIENT INGREDIENT
PWAs use modern web capabilities to provide a reliable, engaging
and fast user experience on any device reliable engaging fast on any device
None
None
NETWORK CONNECTION IS SECURE
None
CAN WORK WITH POOR/NO CONNECTION
DOWNASAUR
Service workers
A service worker is a script that runs in the
background of your browser when you view a webpage
ADDING A SERVICE WORKER 1. Create the file and write
the logic yourself 2. Use a library
None
npm install workbox-cli --global workbox-cli generate:sw
None
<script> if ('serviceWorker' in navigator) { window.addEventListener('load', function () {
navigator.serviceWorker.register('/service-worker.js').then(function(){ // Registration was successful console.log('ServiceWorker registration successful!'); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }); } </script> if ('serviceWorker' in navigator) { window.addEventListener('load', function () { navigator.serviceWorker.register('/service-worker.js') <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function () { navigator.serviceWorker.register('/service-worker.js').then(function(){ // Registration was successful console.log('ServiceWorker registration successful!'); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }); } </script> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function () { navigator.serviceWorker.register('/service-worker.js').then(function(){ // Registration was successful console.log('ServiceWorker registration successful!'); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }); } </script>
None
APPLICATION SHELL
APPLICATION SHELL CONTENT
module.exports = { globDirectory: 'dist/', globPatterns: ['**/*.{js,png,svg,html,json}'], swDest: 'dist/service-worker.js', navigateFallback:
'/index.html' }; module.exports = { globDirectory: 'dist/', globPatterns: ['**/*.{js,png,svg,html,json}'], swDest: 'dist/service-worker.js', navigateFallback: '/index.html', }; module.exports = { globDirectory: 'dist/', globPatterns: ['**/*.{js,png,svg,html,json}'], swDest: 'dist/service-worker.js', navigateFallback: '/index.html' }; globDirectory: 'dist/' globPatterns: ['**/*.{js,png,svg,html,json}'] swDest: 'dist/service-worker.js' navigateFallback: '/index.html'
BUILD PROCESS
npm install workbox-cli --save-dev // package.json "scripts": { //... "build":
"{build} && workbox-cli generate:sw" }
workbox-webpack-plugin
DYNAMIC CONTENT
module.exports = { globDirectory: 'dist/', globPatterns: ['**/*.{js,png,svg,html,json}'], swDest: 'dist/service-worker.js', navigateFallback:
'/index.html', runtimeCaching: [ { urlPattern: /^https:\/\/your.api.com\/.*/, handler: 'networkFirst' } ] }; module.exports = { globDirectory: 'dist/', globPatterns: ['**/*.{js,png,svg,html,json}'], swDest: 'dist/service-worker.js', navigateFallback: '/index.html', runtimeCaching: [ { urlPattern: /^https:\/\/your.api.com\/.*/, handler: 'networkFirst' } ] }; runtimeCaching: [ { urlPattern: /^https:\/\/your.api.com\/.*/, handler: 'networkFirst' } ] runtimeCaching: [ { urlPattern: /^https:\/\/your.api.com\/.*/, handler: 'networkFirst' } ] networkFirst
networkFirst cacheFirst fastest cacheOnly networkOnly
APP SHELL + DYNAMIC CACHING
OFFLINE SUPPORT + FASTER REPEAT VISITS
None
preview.starbucks.com
CAN I HAZ? Under development
PAGE LOAD IS FAST
None
CSS JS PNG
<link rel="preload" as="script" href="script.js"> <link rel="preload" as="script" href="script.js"> <html lang="en">
<head> <link rel="stylesheet" href="styles.css"> </head> <body> <!--(>'-')> <('-'<)--> <script src="script.js"></script> </body> </html>
JS JS
<link rel="preload" as="script" href="script.js"> as="script" <link rel="preload" as="style" href="styles.css"> as="style"
as="font" as="audio" as="image" as="video"
<link rel="prefetch">
preload-webpack-plugin <link rel="preload" href="chunk.cf7bd8260d685f704bd0.js" as="script"> <link rel="prefetch" href="chunk.cf7bd8260d685f704bd0.js">
CAN I HAZ? Partial Support
HTTP/2 Server Push
None
None
Link: </app/style.css>; rel=preload; as=style Link: </app/script.js>; rel=preload; as=script
None
Link: </app/style.css>; rel=preload; as=style; nopush Link: </app/script.js>; rel=preload; as=script
A Comprehensive Guide To HTTP/2 Server Push - Jeremy Wagner
https://rebrand.ly/http2
Pushing too much Pushing unused assets Cache?
Service Worker H2 Push
BUNDLES
4KB - 145KB Size of JS frameworks, gzipped Restuta/framework-sizes.md GIST
CODE SPLITTING
export const routes: Routes = [ { path: '', redirectTo:
'main', pathMatch: 'full' }, { path: 'main', component: MainComponent }, { path: 'details', loadChildren: 'details/details.module#DetailsModule' } ]; export const routes: Routes = [ { path: '', redirectTo: 'main', pathMatch: 'full' }, { path: 'main', component: MainComponent }, { path: 'details', loadChildren: 'details/details.module#DetailsModule' } ]; loadChildren: 'details/details.module#DetailsModule'
import Loadable from 'react-loadable'; import Loading from './loading.component'; const LoadableComponent
= Loadable({ loader: () => import('./details.component'), loading: Loading, });
None
WEBPACK BUNDLE ANALYZER
bundlesize
FIRST MEANINGFUL PAINT TIME TO INTERACTIVE
SHOW SOME CONTENT WITHOUT JAVASCRIPT
<noscript> Sorry, JavaScript needs to be enabled in order to
run this application. </noscript>
SERVER SIDE RENDERING
INSTALL ON YOUR DEVICE
<link rel="manifest" href="/manifest.json">
{ name: "Angular 2 HN", short_name: "Angular 2 HN", icons:
[ { src: "assets/icons/android-chrome-192x192.png", sizes: "192x192", type: "image/png" }, // ... ], theme_color: "#b92b27", background_color: "#ffffff", display: "standalone", orientation: "portrait" }
APP INSTALL BANNER
INSTALL TO HOMESCREEN
SPLASH SCREEN
APP LOADED
CAN I HAZ? Under development
SAFARI ON IOS Can install to homescreen but that’s it…
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="180x180" href="icon.png">
<link rel="apple-touch-icon" sizes="120x120" href="icon-120x120.png"> <link rel="apple-touch-icon" sizes="152x152" href="icon-152x152.png"> <link rel="apple-touch-icon" sizes="180x180" href="icon-180x180.png"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="180x180" href="icon.png"> <link rel="apple-touch-icon" sizes="120x120" href="icon-120x120.png"> <link rel="apple-touch-icon" sizes="152x152" href="icon-152x152.png"> <link rel="apple-touch-icon" sizes="180x180" href="icon-180x180.png">
None
None
Native Progressive Web
Progressive web apps can replace native apps
@hdjirdeh