I'm from Sweden
Credit: https://www.flickr.com/photos/stephenbove/184201987
I'm from Sweden
Credit: https://www.pinterest.com/pin/313352086545358825/
Web lifeWeb developer since
1999
Mozilla community from 2009
Mozilla employee 2011-2014
The web as of today
Web declared dead in 2010
Web declared dead in 2010
Web very much alive in 2016!
Nov 2015, 800 Million users
May 2016, 1 Billion users
The web is dead?
Apps
Web is all browsers
The web & Chrome
Web as of today => Progressive Web Apps
Instant Loading
Service Workers
Both for offline and poornetwork situations
Add to Home Screen
Shortcut on Homescreen
Install banners
Push Notifications
Re-engagement
Relevant, timely, and contextual notifications
Fast
Smooth animations, scrolling and navigation
Secure
HTTPS
Responsive
Adapting content to any screen size
Service workers allow for offline caching
and instant loading.
Smooth animations, scrolling and
navigations keep the experience silky
smooth.
Push notifications and add to
homescreen help users re-engage.
HTTPS secures the connection between you
and your users.
Reliable Fast Engaging Secure
Progressive Web Apps, today
We've come a long way
The web is almighty powerful
It's just the beginning
What we do now is the beginning
What's needed to play
Table stakes
What about the future?
Credit: https://www.flickr.com/photos/mssarakelly/9422242223
Things we'll talk about todayKnowing who the user is
Credentials Management
Paying for things on the web
Connecting with hardware
Physical Web
WebVR
Knowing who the user is
Credit: https://commons.wikimedia.org/wiki/File:Steal_password.jpg
Title Text
Password
Forgot password?
Login
LOGIN
Don’t have an account? Sign up!
Did I use that?
$%&§”%$?!
Hm?
Most likely!
Yes, but which one?Email address
It's hard to type on a mobile device
Most popular password in 2015
1 2 3 4 5 6
2nd most popular password in 2015
password
Smart Lock for passwords
sign-ins assisted per month
8 billion
Sign Up Form
<form id="signup" action="signup.php" method="post"> <input name="display-name" type="text"> <input name="phone" type="text"> <input name="email" type="text"> <input name="password" type="password"> <input type="submit" value="Sign Up!"> </form>
Friendly name? Identifier? Idunno?
Sign Up Form
<form id="signup" action="signup.php" method="post"> <input name="display-name" type="text" autocomplete="name"> <input name="phone" type="text" autocomplete="home tel"> <input name="email" type="text" autocomplete="username"> <input name="password" type="password"> <input type="submit" value="Sign Up!"> </form>
Aha!
Sign In Form
<form id="login" action="login.php" method="post"> <input name="username" type="text" autocomplete="username"> <input name="password" type="password" autocomplete="current-password"> <input type="submit" value="Sign In!"> </form>
Sign Up Form
<form id="signup" action="signup.php" method="post"> <input name="display-name" type="text" autocomplete="name"> <input name="phone" type="text" autocomplete="home tel"> <input name="email" type="text" autocomplete="username"> <input name="password" type="password" autocomplete="new-password"> <input type="submit" value="Sign Up!"> </form>
password
auto-generated password
7nUvA8jyowEk44
the Credentials Management API
Credit: https://commons.wikimedia.org/wiki/File:Michael_de_la_Force_Leaders_Magazine_Press_Credentials_2013.jpg
Automatic Sign-in
navigator.credentials.get({ "password": true, "unmediated": true }).then(c => { if (!c) return; // Hooray, we have a credential! signInToYourApplication(c); });
Automatic Sign-in
Chrome will offer automatic sign-in if and only if:
✓Automatic sign-in is enabled
✓Only one credential is saved for the site
Automatic Sign-in
✓navigator.credentials is restricted to secure contexts
✓Passwords are not directly exposed to JavaScript
✓fetch() will only submit credentials to same-site endpoint
function signInToYourApplication(c) { fetch("/signin", { "method": "POST", "credentials": c }).then(r => { if (r.status == 200) renderSignedInExperience(r); else renderUsefulErrorMessage(); });}
One-tap Sign-in
navigator.credentials.get({ "password": true }).then(c => { if (!c) return; // Hooray, we have a credential! signInToYourApplication(c); });
Storing credentials
var f = document.querySelector("#form");var c = new PasswordCredential(f);navigator.credentials.store(c) .then(_ => { // ... });
Federated log-ins
var c = new FederatedCredential({ "id": "username", "provider": "https://accounts.google.com"});navigator.credentials.store(c) .then(_ => { // ... });
navigator.credentials .requireUserMediation() .then(_ => { // Sign the user out. });
Logging out
Paying for things on the web
Credit: http://www.publicdomainpictures.net/view-image.php?image=149197
66%of purchases on mobile are on web
66%Fewer conversions on mobile websites vs. desktop
Have you ever abandoned a purchase
because of the checkout form?
Manual Tedious Slow N-taps
Checkout forms today
Autofill Fill web forms with a single click
Card and address saved to Chrome
Automatic form detection
95% ACCURACY
Form filled automatically
How Autofill works
XYZ
25 Increase in conversion rate from Autofill
%
Manual Tedious Slow N-taps
Checkout with Autofill
Automatic Simple
Imagine a world without forms...
PaymentRequest A W3C API to eliminate checkout forms for users and standardize payment collection for sites
Designing PaymentRequest at W3C
Cross-browser
Designing PaymentRequest at W3C
Cross-browser Open ecosystemCross-platform
N-tapsSlowManual Tedious
Checkout with PaymentRequest
Automatic Simple Fast 1-tap
new PaymentRequest( [“visa“, “mastercard“, “amex“, “discover“], { items: [ { id: "basket", label: "Sub-total", amount: { currencyCode: "USD", value: "55.00" }, // $55.00 }, { id: "tax", label: "Sales Tax", amount: { currencyCode: "USD", value: "5.00" }, // $5.00 }, { id: "total", label: "Total excluding shipping", amount: { currencyCode: "USD", value: "60.00" }, // $60.00 } ] }, { requestShipping: true } ).show().then(response => { /* process payment */ }).catch(error => { /* handle */ });
new PaymentRequest( [“visa“, “mastercard“, “amex“, “discover“], { items: [ { id: "basket", label: "Sub-total", amount: { currencyCode: "USD", value: "55.00" }, // $55.00 }, { id: "tax", label: "Sales Tax", amount: { currencyCode: "USD", value: "5.00" }, // $5.00 }, { id: "total", label: "Total excluding shipping", amount: { currencyCode: "USD", value: "60.00" }, // $60.00 } ] }, { requestShipping: true } ).show().then(response => { /* process payment */ }).catch(error => { /* handle */ });
var request = new PaymentRequest( [“visa”, ..., “https://android.com/pay”], // add Android Pay as supported { items: [...] }, { requestShipping: true }, { // add Android Pay application specific parameters "https://android.com/pay": { "gateway": "stripe", "stripe:publishableKey": "put_your_stripe_publishable_key_here", "stripe:version": "2015-10-16 (latest)" } } );
PaymentRequest with Autofill cards in
Chrome Dev Android
PaymentRequest available in Chrome
Beta on mobile; Android Pay
Support for all platforms & 3rd party
payment apps
May 2016 Aug 2016 Early 2017
When can I use PaymentRequest?
Connecting with hardware
Credit: Kenneth Rohde Christiansen
The evolution of transfer rates
Wi-Fi (Mbps)
802.11: 2 802.11b: 11 802.11g: 54 802.11n: 135
Ethernet (Mbps)
802.3i: 10 802.3u: 100 802.3ab: 1000 802.3an: 10000
Bluetooth (Mbps)
1.1: 1 2.0: 3 3.0: 54 4.0: 0.3
Demo time!https://webbluetoothcg.github.io/demos/playbulb-candle/
Basic BLE terms to know...
“Central” device (my phone) “Peripheral” device (candle) GATT (Generic ATTribute profile)
var options = { filters: [{ services: [’battery_service’] }] };
navigator.bluetooth.requestDevice(options).then(device => { console.log(device.name); ...}).catch(error => { console.log(error); });
var options = { filters: [{ services: [’battery_service’] }] };
navigator.bluetooth.requestDevice(options).then(device => device.gatt.connect()).then(server => { ... }).catch(error => { console.log(error); });
var options = { filters: [{ services: [’battery_service'] }] };
navigator.bluetooth.requestDevice(options).then(device => device.gatt.connect()).then(server => server.getPrimaryService(’battery_service’)).then(service => service.getCharacteristic(’battery_level’)).then(characteristic => characteristic.readValue()).then(value => { console.log(’Battery percentage is ’ + value.getUint8(0));}).catch(error => { console.log(error); });
var options = { filters: [{ services: [CANDLE_SERVICE_UUID] }], optionalServices: ['battery_service'] };navigator.bluetooth.requestDevice(options).then(device => device.gatt.connect()).then(server => server.getPrimaryService(CANDLE_SERVICE_UUID)).then(service => service.getCharacteristic(CANDLE_COLOR_UUID)).then(characteristic => { let data = [0x00, r, g, b, 0x05, 0x00, 0x01, 0x00]; return characteristic.writeValue(new Uint8Array(data));}).catch(error => { console.log(error); });
Android Developer Options
var options = { filters: [{ services: [CANDLE_SERVICE_UUID] }] };
navigator.bluetooth.requestDevice(options).then(device => device.gatt.connect()).then(server => server.getPrimaryService(CANDLE_SERVICE_UUID)).then(service => service.getCharacteristic(CANDLE_BLOW_NOTIFICATIONS_UUID)).then(characteristic => { characteristic.addEventListener(’characteristicvaluechanged’, blow); return characteristic.startNotifications(); }).catch(error => { console.log(error); });
function blow(event) { console.log(event.target.value); }
WebNFC
navigator.nfc.watch((message) => { for (let record of message.data) { let article =/[aeio]/.test(record.data.title) ? "an" : "a"; console.log( `$(record.data.name) is $(article) $(record.data.title)` ); }}, { url: document.baseURI, recordType: "json" });
Your local hero
Generic Sensors
let sensor = new DirectTirePressureSensor({ position: "rear", side: "left" });sensor.onchange = event => console.log(event.reading.pressure);
try { // No need to feature detect thanks to try..catch block. let sensor = new GeolocationSensor({}); sensor.start(); sensor.onerror = error => gracefullyDegrade(error); sensor.onchange = event => updatePosition(event.reading.coords);} catch(error) { gracefullyDegrade(error);}
The Physical Web
http://www.physical-web.org
Credit: https://en.wikipedia.org/wiki/Spider_web
/* Awesomeness to come */
var referringDevice = navigator.bluetooth.referringDevice;
if (referringDevice) { referringDevice.gatt.connect() .then(server => { ... }) .catch(error => { console.log(error); });}
Virtual Reality, WebVR
WebVR API 1.0 progress!
Landing in browsers:
Firefox Nightly 2 weeks ago Chrome later this year
Daydream
Daydream
VR View
Oculus CEO & co-founder
Tell us what you needReport bug https://crbug.com
Feature statushttps://chromestatus.com
Slackhttps://goo.gl/jCWx5m
Videos https://www.youtube.com/user/ChromeDevelopers
@ChromiumDev
Credit: https://github.com/alrra/browser-logos
Working together on making the web better Credit: https://twitter.com/simonnricketts/status/699198327338987520
The Future of the Web