Eugene Mutai
Being a Fullstack Ninja at @Andela | Google Developer Expert #GDE | #MEAN | @NairobiJS community lead. Making things happen. Telling better stories.
#pwaroadshow
<!DOCTYPE html>
<html lang="en">
<head>
<title>Your awesome site -- Homepage</title>
...
<link rel="stylesheet" type="text/css" href="./css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="./css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="./css/application.css" />
<link rel="stylesheet" type="text/css" href="./css/section.css?" />
<link rel="stylesheet" type="text/css" href="./css/prefixed-main.css" />
<link rel="stylesheet" href="./css/main.css">
</head>
<body>
...
<script type="text/javascript" src="./vendor/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="./vendor/angularjs/angular.min.js"></script>
<script type="text/javascript" src="./vendor/jquery-cookie/jquery.cookie.js"></script>
<script type="text/javascript" src="./vendor/hammerjs/hammer.min.js"></script>
<script type="text/javascript" src="./vendor/moment/min/moment.min.js"></script>
<script type="text/javascript" src="./js/main.js"></script>
<script>
// initialise the application.
app.initialize();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Your awesome site -- Homepage</title>
...
<style>
/*
Your application's shell styling here
body{padding: 10px ... }
header{color: #000; text: #FFF ... }
*/
</style>
<script type="text/javascript">
function loadCSS(cssPath) { ... }
</script>
</head>
<body>
<!--
The 1st render should happen server-side
This way the user get's content immediately
as you go on to fetch more for the currently satisfied user
-->
...
<!-- Load the script asyncronously -->
<script type="text/javascript" src="./lib/all-the-other-code.min.js" async></script>
</body>
</html>
non-blocking
It's likely I won't read it
A service worker has a lot of power. We wouldn't want it to fall into the wrong hands.
With the release of the Push and Notification Web APIs, The user can receive push notifications even when the web app is closed.
Google Plus hit their goal of never downloading more than 60k of HTML, 60k of JavaScript and 60k of CSS at any one time!
{
name: "My Awesome Web App",
short_name: "Awesome App",
icons: [{
src: "images/touch/icon-96x96.png",
sizes: "96x96",
type: "image/png"
}, {
src: "images/touch/icon-128x128.png",
sizes: "128x128",
type: "image/png"
}, {
src: "images/touch/apple-touch-icon.png",
sizes: "152x152",
type: "image/png"
}, {
src: "images/touch/chrome-touch-icon-192x192.png",
sizes: "192x192",
type: "image/png"
}],
start_url: "/index.html?homescreen=1",
display: "standalone",
background_color: "#3E4EB8",
theme_color: "#2F3BA2"
}
<link rel="manifest" href="./manifest.json"></link>
A service worker is a client side network proxy. But that's not the only trick it has up it's sleeves.
// Register the ServiceWorker
navigator.serviceWorker
.register('sw-script.js', {
scope: '.'
}).then((registration) => {
// The service worker has been registered!
});
// http://bit.ly/sw-lifecycle
self.addEventListener('install', (event) => {
// Service worker has been downloaded and installed.
// Your 1st task can be to cache the app shell
// preparing it to work offline
});
self.addEventListener('activate', (event) => {
// Has now been installed.
// Maybe finish the setup
// Or clean up old resources cached
});
self.addEventListener('fetch', (event) => {
// Watch for every event and do something
// for every single request
// being made by the client to the server
});
SW life cycle
Registration
var CACHE_NAME = 'dependencies-cache';
// Files required to make this app work offline
var REQUIRED_FILES = [
'random-1.png',
'random-2.png',
'random-3.png',
'style.css',
'index.html',
'/', // Separate URL than index.html!
'index.js',
'app.js'
];
self.addEventListener('install', (event) => {
// Perform install step:
// loading each required file into cache
event.waitUntil(
caches.open(CACHE_NAME)
// Add all offline dependencies to the cache
.then((cache) => {
return cache.addAll(REQUIRED_FILES));
})
// At this point everything has been cached
.then(() => self.skipWaiting())
);
});
A service worker can then use the Cache API to cache the app's shell: basically the applications layout styles and business logic.
service-worker.js
The service worker provides access to the Cache API. The app shell can be cached. It then has everything it needs to work offline and fast.
Content the user has seen can then be cached. Just like native apps. Even when offline, content is still KING.
The service worker's background sync feature has your back (literally).
Your user’s are already real users the minute they land on your page.
Your user’s are already real users the minute they land on your page.
By Eugene Mutai
This is an introduction to the future of web apps. With the introduction of several new Web APIs leveling the playing field for web apps to native apps. The web and native mobile apps are about to go on a head to head battle of user experience.
Being a Fullstack Ninja at @Andela | Google Developer Expert #GDE | #MEAN | @NairobiJS community lead. Making things happen. Telling better stories.