Progressive Web Apps


...the future of web apps


Social: @kn9ts


450+ million


The number of mobile subscribers in Africa as of 2015 (Q1)


51% growth


predicted between 2014 and 2020


75% purchases being 



predicted between 2014 and 2020




expected to be cut in half by 2020 by upgrades to 3G/WCDMA


The rest of the world will be in 4G


 40 - 250 kbps


The range of a 2G/EDGE connection







Why not Web?


Smartphones run on Android...duh!


OK! Then what about apps?


Do web apps come into mind when thinking about apps?


NOT at first! 


They are not native apps.
They are apps that work in a browser ONLY.


Everybody here!


I would create a native app


If I am targeting mobile subscribers.


Everybody here!


Or use meteorjs or phonegap


To create a HYBRID native mobile app.


Everybody here!


define the word app?!


What makes an app feel 'appy'??? :)


The network 

is always unpredictable.

I want a fast app.


The web is not that fast!


If there's no network. I want my app to work offline, for real!


The web can't do that!


I want my app to have push notifications.


The web can't do that!


I want my app to be installed!


The web can't do that!


The web can't do that!


The web CAN do that!


And even BETTER!


Performance: App shell model

<!DOCTYPE html>
<html lang="en">

    <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">


    <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>
        // initialise the application.


A lot LESS of this.

<!DOCTYPE html>
<html lang="en">

    <title>Your awesome site -- Homepage</title>
        Your application's shell styling here
        body{padding: 10px ... }
        header{color: #000; text: #FFF ... }
    <script type="text/javascript">
        function loadCSS(cssPath) { ... }

    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>


A lot MORE of this.


Impact of performance.





  • Focus on the user; the end goal isn't to make your site perform fast on any specific device, it's to ultimately make users happy.

  • Respond to users immediately; acknowledge user input in under 100ms.

  • Render each frame in under 16ms and aim for consistency; users notice 'jank'.

  • Maximize main thread idle time.

  • Keep users engaged; deliver interactive content in under 1000ms.

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.

Re-engages the user.

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!

Once we've done all we can do.


We progress to enhancing the app to a

Progressive Web App


A progressive web app uses modern web capabilities to deliver an app-like user experience. They evolve from pages in browser tabs to immersive, top-level apps, leveraging the web's low friction.


Progressive web apps properties:

  • Progressive

  • Responsive

  • Connectivity Independent

  • App-like

  • Fresh

  • Safe

  • Discoverable 

  • Installable

  • Re-engable 

  • Linkable (it's the web)


The Heuristics


How can you join the movement?

    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>

Let the browser know. we add this to the <head>


A Service Worker

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
    .register('sw-script.js', {
      scope: '.'
    }).then((registration) => {
      // The service worker has been registered!
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



var CACHE_NAME = 'dependencies-cache';

// Files required to make this app work offline
  '/', // Separate URL than index.html!

self.addEventListener('install', (event) => {
  // Perform install step:  
  // loading each required file into cache
      // Add all offline dependencies to the cache
      .then((cache) => {
          return cache.addAll(REQUIRED_FILES));
      // At this point everything has been cached
      .then(() => self.skipWaiting())

Cache the App Shell

A service worker can then use the Cache API to cache the app's shell: basically the applications layout styles and business logic.

FASTEN the curr. FAST load!


Network Independent

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.


is King.

Content the user has seen can then be cached. Just like native apps. Even when offline, content is still KING.

“it is better to have yesterday result instantly than to wait too long for today's data.”


Syncs in the background.

The service worker's background sync feature has your back (literally).

Web APIs awareness:

  • Geolocation

  • Fetch API (replaces XMLHttpRequest)

  • IndexedDB (for the SQLite guys)

  • Web Bluetooth

  • WebRTC

  • Battery API

  • Accelerometer API

  • And many more


Take advantage of the web's low friction.


This is the greatest weapon the web has.


"In a consumer app, every step you make the users take to access your services costs you 20% of your users."


Find the app!


click install


accept permissions




use the app








Find the app!



...and use it!


The web solves a number of challenges native 

mobile apps have:

  • Installs are not an issue

  • Have no APK size restrictions

  • Are always up-to-date (do not require re-installs for an update to happen)

  • They work everywhere (a browser is)

  • Tend to be trusted more than native apps


Am hoping to see a lot

less of this.

Your user’s are already  real users the minute they land on your page.

And see

more of this.

Your user’s are already  real users the minute they land on your page.

Eugene Mutai/@kn9ts

Made with