APIs for modern web apps

Post on 23-Feb-2017

496 views 0 download

transcript

APIsfor modern web apps

chris mills, mozillA

Get the slides!•Don’t worry about notes •You can get the slides from slideshare.net/

chrisdavidmills •Sit back and relax •Or fidget if you get bored… •Ask questions at @chrisdavidmills or

cmills@mozilla.com

who am i?•I’m Chris •Mozilla, MDN writer •Twiddling around with JS/CSS/HTML •APIs •Educational material •Accessibility whiner •Heavy metal drummer

APIslike, what are we talking about?

•I really mean browser JavaScript APIs •Exposing complex functionality to JS •Making the Web more powerful and useful

api, why oh why?

•For a time, we only really had a few APIs •We had DOM stuff, and XHR •(And a bunch of horrid non-standard stuff) •But the scene exploded •WHATWG, Web Apps WG, and others

api, why oh why?

•Earlier APIs added interesting new features •E.g. Geolocation, Canvas •But this still wasn’t enough

api, why oh why?

•We want to remain competitive with native •Get everything working together more

cohesively •Deal with multimedia effectively in the

browser •Improve performance, for games, etc. •Improve internationalization

api, why oh why?

catching nativeprogressive apps

•Native platforms had better functionality •We want to catch up, and make it webby

web versus native

•The Web is a good thing •Progressive enhancement •No app stores •You can’t cache seamlessly on native, or

render text easily/fluidly

we love web

•Installable/discoverable •Offline •Re-engageable •Linkable •Responsive •Safe •and of course, Progressive

progressive apps

Installablei got you under my skin

installing apps

•The web can do this too! •Without app stores •Web App Manifest defines app features •Including icons, background, splash screen,

theme colors… •App files cached on device too (see later)

installing apps

Manifest example{ "name": "My sample app", "short_name": "MY app", "start_url": "./?utm_source=web_app_manifest", "display": "standalone", "icons": [{ "src": "images/touch/homescreen48.png", "sizes": "48x48", "type": "image/png" }, { "src": "images/touch/homescreen72.png", "sizes": "72x72", "type": "image/png" }, { "src": "images/touch/homescreen96.png", "sizes": "96x96",

•Also helps with discoverability •The web largely does this anyway •Standardised metadata mechanism is nice •Better represent apps on search results,

social media, (app stores?!) etc.

discoverability

we already do it<meta property="og:description" content="Add-ons …"> <meta name="description" content="Add-ons add …"> <meta name="twitter:description" content="Add-ons add …”>

offlinestill a problem?

No connection = no experience

•Offline data storage •Offline asset storage •Reacting to network changes

offline is hard

•Not so bad •We have storage mechanisms (e.g.

IndexedDB, Web Storage, WebSQL) •Something available in most browsers •Plus polyfills (e.g. LocalForage)

offline data

•More of a pain •We had AppCache…

offline assets

CACHE MANIFEST # v1

CACHE: css/app.css index.html js/main.js js/lib/require.js

this had promise

•It’s actually fairly useless •Too much voodoo… •Assumed a specific set of behaviours

but….

Hello service workers!

•Proxy servers that sit between app and network

•Intercepting network requests and customising responses

•Does similar things to AppCache (plus a lot more…much harder to use)

•Granular control over actions

sw are cool

if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/*' }).then(function(sw) { // registration worked console.log('Registration succeeded.'); }).catch(function() { // registration failed console.log('Registration failed.'); }); }

registration

this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1').then(function(cache) { return cache.addAll([ '/sw-test/', '/sw-test/index.html', '/sw-test/style.css', '/sw-test/app.js', '/sw-test/image-list.js', '/sw-test/star-wars-logo.jpg', '/sw-test/gallery/bountyHunters.jpg', '/sw-test/gallery/myLittleVader.jpg', '/sw-test/gallery/snowTroopers.jpg' ]); }) ); });

installation

this.addEventListener('fetch', function(event) { var response; event.respondWith(caches.match(event.request) .catch(function() { return fetch(event.request); }).then(function(r) { response = r; caches.open('v1').then(function(cache) { cache.put(event.request, response); }); return response.clone(); }).catch(function() { return caches.match(‘/sw-test/gallery/ myLittleVader.jpg'); })); });

custom responses

•The app container should be lightweight HTML/CSS/JS

•Load fast, be cached, load on repeat visits •The content should then update dynamically •See Instant Loading Web Apps with An

Application Shell Architecture

App shell

reengagementhey, come back!!!

•You have new followers •Your friend posted a new photo •Your pokemon wants another fight •You have mail •The government wants to read your mail •etc.

hello users

•Native was always good at reengagement •Now web can do it too, even when the app

isn’t being used •Push API •Notifications API •Channel Messaging API

•etc.

People love it

•Needs an active SW controlling the app •Subscribe to push messages •Send special endpoint to your server (URL) •Send messages to this endpoint •Push server sends them to the SW

needs a sw

navigator.serviceWorker.ready.then(function(reg) { reg.pushManager.getSubscription() .then(function(subscription) { // Enable any UI for subscribing to push messages. var endpoint = subscription.endpoint; updateStatus(endpoint,'init'); }).catch(function(err) { console.log('Error during getSubscription()', err); }); });

push

self.addEventListener('push', function(event) { var obj = event.data.json(); event.waitUntil( self.registration.showNotification(title, { body: obj.name + ‘ has subscribed.’, icon: icon, tag: tag }) ); });

notifications

var channel = new MessageChannel(); channel.port1.onmessage = function(e) { alert(e.data); } mySW = reg.active; mySW.postMessage('hello', [channel.port2]);

channel msg

var port;

self.onmessage = function(e) { port = e.ports[0]; } port.postMessage(obj);

continuityspecs working together

•Creating extra work, repetition, and confusion

•E.g. CSS and SVG functionality overlap •Led to them forming the FXTF •More care taken these days •Extensible web manifesto — modular and

explainable

silos aren’t cool

•Fetch is a good example •Similar to what XHR does •Abstracts the whole request/response model

as JS objects •So it can be used with other APIs like

Service Workers

fetch / sw

•Other specs also work well with/are based on SW: •Notifications API •Push API •Channel Messaging

•They all contain partial additions for SW

sw add-ons

mediaweb audio visuals

•Media was broken for years on the Web •Audio/video delivery needed Flash for so

long •The <video> tag took long enough

fix media

•WebRTC/gUM for accessing streams •Should solve many use cases, from simple

image capture, video streaming, up to multi-person video conferencing

•What about recording? •Media Recorder API

media capture

var constraints = { audio: true, video: true };

var p = navigator.mediaDevices.getUserMedia(constraints);

p.then(function(stream) { // do something with the stream in here });

p.catch(function(err) { console.log(err.name); });

getusermedia

var mediaRecorder = new MediaRecorder(stream);

record.onclick = function() { mediaRecorder.start(); }

stop.onclick = function() { mediaRecorder.stop(); }

mediaRecorder.ondataavailable = function(e) { var video = document.createElement('video'); video.setAttribute('controls', ''); var videoURL = window.URL.createObjectURL(e.data); video.src = videoURL; }

media recorder

•Media Source Extensions •Encrypted Media Extensions •DRM on the Web?!? •A necessary evil, WRT services like

Netflix..? •Netflix involved in both the above specs

streaming/drm

•Web Audio API •Precise audio control •Add effects •Split and merge audio channels •Spatialization •Audio visualizations

audio processing

Performancefaster and faster…

I18ninternationalization

•The Web is international •But adapting sites for an intl. audience is a

pain •E.g. Dealing with time/date formats •And BIDI websites •But we are working on this too

i18n

var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

console.log(new Intl.DateTimeFormat().format(date));console.log(new Intl.DateTimeFormat('en-US').format(date)); // DateTimeFormat without arguments returns the // correct value for the language/timezone.

JavaScript i18n api•The JS Internationalization API provides

features for formatting dates/times for different languages, etc.

#content { padding-left: 12px: margin-right: 20px; }

html[dir="rtl"] #content { padding-left: 0; padding-right: 12px; margin-right: 0; margin-left: 20px; }

CSS BIDI features•BIDI websites are simpler to layout with CSS

BIDI features

#content { padding-inline-start: 12px: margin-inline-end: 20px; }

CSS BIDI features

FinitoThanks for listening!

@chrisdavidmills, cmills@mozilla.com slideshare.net/chrisdavidmills

•Main image: Bokeh Dandelion, by Nicolas Raymond

credits