Browser is the new server

Dr. Gleb Bahmutov PhD

NodeFest Tokyo 2016

Work at Kensho

A DATA ANALYTICS AND MACHINE INTELLIGENCE COMPANY

Boston / NYC

I love solving AngularJS performance problems

How to quickly start a web app?

Using CDN, parallel downloads, caching, small images, above the fold, etc.

PivotalTracker HOT reload

why am I waiting?

The data does not change between the reloads*

I do not interact with the page in the first 500ms

nice

what?

app

HTML

data

loads

renders

HTML = APP(data)

same

same

app

HTML

data

loads

HTML = APP(data)

Cache

Cache

idea!

renders

Hydration

There is a flash 😢

Server-side rendering 👍

The page HTML arrives ready to be rendered by the browser

The browsers are REALLY REALLY good at rendering static pages

If only there was a way to give browser the full page from a web app

ServiceWorker

Server

browser

Web Workers

ServiceWorker

Transforms

the response

Transforms

the request

Smart caching

OFFLINE SUPPORT

Image / video transcoding

Background data sync

Server

browser

service

worker

No changes to the page 😊

Load ServiceWorker

navigator.serviceWorker.register(
    'app/my-service-worker.js')

Chrome, Opera, Firefox

Must be https

Inside ServiceWorker

self.addEventListener('install', ...)
self.addEventListener('activate', ...)
self.addEventListener('message', ...)
self.addEventListener('push', ...)
self.addEventListener('fetch', function (event) {
  console.log(event.request.url)
  event.respondWith(...)
})
// Cache API

Instant pages using SW: Bottle-service

Server

browser

ServiceWorker

<html>
<body>
  <header>...</header>
  <div id="app"></div>
  <footer>...</footer>
</body>
</html>
<html>
<body>
  <header>...</header>
  <div id="app">
   <ul>
     <li>Clean my room</li>
     ...
   </ul>
  </div>
  <footer>...</footer>
</body>
</html>
<ul>
  <li>Clean my room</li>
  ...
</ul>

Cache

Inserts cached HTML fragment into response body HTML

Instant pages using SW: Bottle-service

If the server goes down in the forest ...

Stop treating browser like a child

Fetch event

browser

ServiceWorker

Request

Response

Server

Server

browser

ServiceWorker

Request

Response

express.js

http.ClientRequest

JavaScript

http.ServerResponse

JavaScript

Fetch event

browser

ServiceWorker

Server

express.js

child-like app

Server

browser

ServiceWorker

express.js

http.ClientRequest(Request)

http.ServerResponse(Response)

grown up app using SW

express.js + middleware

ServiceWorker env

browserify

const expressService = require('express-service')
const app = require('todomvc-express')
const urls = ['/', 'app.css']
const cacheName = require('./package.json').name
expressService(app, urls, cacheName)

"app" is a regular Express.js application

Express-service

Express-service

Express-service

There is no client-side* JavaScript :)

<link rel="serviceworker" scope="/" href="/sw.js">

*after first ServiceWorker registration

Express-service

bonus

$ npm i -g nativefier
$ nativefier https://express-service.gleb-demos.com/
Packaging app for platform darwin x64 using electron v1.1.3
App built to /Users/gleb/git/ExpressService-darwin-x64

Express-service stand alone desktop app

want to know more?

isomorphic

universal

jumping?

grown up?

independent?

need good name

Browser is the new server

Instant apps

Server in the browser

Code transpiling, coverage, testing