42
Web improvements @robertnyman

New improvements for web developers - frontend.fi, Helsinki

Embed Size (px)

Citation preview

Page 1: New improvements for web developers - frontend.fi, Helsinki

Web improvements @robertnyman

Page 2: New improvements for web developers - frontend.fi, Helsinki

Promises

Page 3: New improvements for web developers - frontend.fi, Helsinki
Page 4: New improvements for web developers - frontend.fi, Helsinki

fulfilled = The action relating to the promise succeeded

rejected = The action relating to the promise failed

pending = Hasn't fulfilled or rejected yet

settled = Has fulfilled or rejected

Page 5: New improvements for web developers - frontend.fi, Helsinki

var promise = new Promise(function(resolve, reject) { // do a thing, possibly async, then… if (/* everything turned out fine */) { resolve("Stuff worked!"); } else { reject(Error("It broke")); }});

Page 6: New improvements for web developers - frontend.fi, Helsinki

promise.then(function(result) { console.log(result); // "Stuff worked!"}, function(err) { console.log(err); // Error: "It broke"});

Page 7: New improvements for web developers - frontend.fi, Helsinki

fetch()

Page 8: New improvements for web developers - frontend.fi, Helsinki

XMLHttpRequest example

function reqListener() { var data = JSON.parse(this.responseText); console.log(data); } function reqError(err) { console.log('Fetch Error :-S', err); } var oReq = new XMLHttpRequest(); oReq.onload = reqListener; oReq.onerror = reqError; oReq.open('get', './api/some.json', true); oReq.send();

Page 9: New improvements for web developers - frontend.fi, Helsinki

fetch() version

fetch('./api/some.json') .then( function(response) { if (response.status !== 200) { console.log('Looks like there was a problem. Status Code: ' + response.status); return; } // Examine the text in the response response.json().then(function(data) { console.log(data); }); } ) .catch(function(err) { console.log('Fetch Error :-S', err); });

Page 10: New improvements for web developers - frontend.fi, Helsinki

Response metadata

fetch('users.json').then(function(response) { console.log(response.headers.get('Content-Type')); console.log(response.headers.get('Date')); console.log(response.status); console.log(response.statusText); console.log(response.type); console.log(response.url); });

Page 11: New improvements for web developers - frontend.fi, Helsinki

Response Types

basic

cors

opaque

Page 12: New improvements for web developers - frontend.fi, Helsinki

Defining modes

same-origin

cors

cors-with-forced-preflight

no-cors

Page 13: New improvements for web developers - frontend.fi, Helsinki

Defining modes

fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'}) .then(function(response) { return response.text(); }) .then(function(text) { console.log('Request successful', text); }) .catch(function(error) { log('Request failed', error) });

Page 14: New improvements for web developers - frontend.fi, Helsinki

Service Workers

Page 15: New improvements for web developers - frontend.fi, Helsinki

It's a JavaScript Worker, so it can't access the DOM directly. Instead responds to postMessages

Service worker is a programmable network proxy

It will be terminated when not in use, and restarted when it's next needed

Makes extensive use of Promises

Page 16: New improvements for web developers - frontend.fi, Helsinki
Page 17: New improvements for web developers - frontend.fi, Helsinki

No Service Worker

Page 18: New improvements for web developers - frontend.fi, Helsinki

HTTPS is Needed

Page 19: New improvements for web developers - frontend.fi, Helsinki

Register and Installing a Service Worker

if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); });}

Page 20: New improvements for web developers - frontend.fi, Helsinki

chrome://inspect/#service-workers

Page 21: New improvements for web developers - frontend.fi, Helsinki

// The files we want to cachevar urlsToCache = [ '/', '/styles/main.css', '/script/main.js']; // Set the callback for the install stepself.addEventListener('install', function(event) { // Perform install steps});

Installing

Page 22: New improvements for web developers - frontend.fi, Helsinki

Inside our install callback:

1. Open a cache 2. Cache our files 3. Confirm whether all the required assets are cached or not

Page 23: New improvements for web developers - frontend.fi, Helsinki

Install callback

var CACHE_NAME = 'my-site-cache-v1'; var urlsToCache = [ '/', '/styles/main.css', '/script/main.js']; self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); }) );});

Page 24: New improvements for web developers - frontend.fi, Helsinki

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } return fetch(event.request); } ) );});

Caching and Returning Requests

Page 25: New improvements for web developers - frontend.fi, Helsinki

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } // IMPORTANT: Clone the request. A request is a stream and // can only be consumed once. Since we are consuming this // once by cache and once by the browser for fetch, we need // to clone the response var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) );});

Caching new requests cumulatively

Page 26: New improvements for web developers - frontend.fi, Helsinki

Updating a Service Worker

Page 27: New improvements for web developers - frontend.fi, Helsinki

1. Update your service worker JavaScript file. 2. Your new service worker will be started and the

install event will be fired. 3. New Service Worker will enter a "waiting" state 4. When open pages are closed, the old Service

Worker will be killed - new service worker will take control.

5. Once new Service Worker takes control, its activate event will be fired.

Updating a Service Worker

Page 28: New improvements for web developers - frontend.fi, Helsinki

Cache management & whitelists

self.addEventListener('activate', function(event) { var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) );});

Page 29: New improvements for web developers - frontend.fi, Helsinki

Push notifications

Page 30: New improvements for web developers - frontend.fi, Helsinki
Page 31: New improvements for web developers - frontend.fi, Helsinki

<button class="js-push-button" disabled> Enable Push Messages </button>

Page 32: New improvements for web developers - frontend.fi, Helsinki

// Are Notifications supported in the service worker? if (!('showNotification' in ServiceWorkerRegistration.prototype)) { console.warn('Notifications aren\'t supported.'); return; }

Page 33: New improvements for web developers - frontend.fi, Helsinki

// Check the current Notification permission. // If its denied, it's a permanent block until the // user changes the permission if (Notification.permission === 'denied') { console.warn('The user has blocked notifications.'); return; }

Page 34: New improvements for web developers - frontend.fi, Helsinki

// Check if push messaging is supported if (!('PushManager' in window)) { console.warn('Push messaging isn\'t supported.'); return; }

Page 35: New improvements for web developers - frontend.fi, Helsinki

// We need the service worker registration to check for a subscription navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { // Do we already have a push message subscription? serviceWorkerRegistration.pushManager.getSubscription() .then(function(subscription) { // Enable any UI which subscribes / unsubscribes from // push messages. var pushButton = document.querySelector('.js-push-button'); pushButton.disabled = false; if (!subscription) { // We aren't subscribed to push, so set UI // to allow the user to enable push return; } // Keep your server in sync with the latest subscriptionId sendSubscriptionToServer(subscription); // Set your UI to show they have subscribed for // push messages pushButton.textContent = 'Disable Push Messages'; isPushEnabled = true; }) .catch(function(err) { console.warn('Error during getSubscription()', err); }); });

Page 36: New improvements for web developers - frontend.fi, Helsinki

{ "name": "Push Demo", "short_name": "Push Demo", "icons": [{ "src": "images/icon-192x192.png", "sizes": "192x192", "type": "image/png" }], "start_url": "/index.html?homescreen=1", "display": "standalone", "gcm_sender_id": "123456789012", "gcm_user_visible_only": true }

<link rel="manifest" href="manifest.json">

Page 37: New improvements for web developers - frontend.fi, Helsinki

Add to Homescreen

Page 38: New improvements for web developers - frontend.fi, Helsinki

Cache management & whitelistsApp Install Banners

Page 39: New improvements for web developers - frontend.fi, Helsinki

App Install Banners prerequisites

You have a web app manifest file

You have a service worker registered on your site. We recommend a simple custom offline page service worker

Your site is served over HTTPS (you need a service worker after all)

The user has visited your site twice over two separate days during the course of two weeks.