Progressive Web Apps are one of the hottest things to come to the web platform in years, but how much of it is just hot air? When can you actually start shipping these things? Decades ago! In a hands on presentation, I'll show how PWAs are truly meant to be progressive - building on an evolution of web technologies nearly as old as the web itself, and still let you ship one of the most performant and cutting edge web apps around.
107. let cheerio = require(âcheerio')
let cld = require('cld')
let getLang = (html, callback) => {
let $ = cheerio.load(html)
let lang = $('html[lang]').attr(âlang')
if (!lang) {
lang = $('html[xml:lang]').attr(âxml:langâ)
}
if (!lang) {
lang = $(âmeta[name:âdc.languageâ]').attr(âcontentâ)
}
...
108. let cheerio = require(âcheerio')
let cld = require('cld')
let getLang = (html, callback) => {
let $ = cheerio.load(html)
let lang = $('html[lang]').attr(âlang')
if (!lang) {
lang = $('html[xml:lang]').attr(âxml:langâ)
}
if (!lang) {
lang = $(âmeta[name:âdc.languageâ]').attr(âcontentâ)
}
...
109. let cheerio = require(âcheerio')
let cld = require('cld')
let getLang = (html, callback) => {
let $ = cheerio.load(html)
let lang = $('html[lang]').attr(âlang')
if (!lang) {
lang = $('html[xml:lang]').attr(âxml:langâ)
}
if (!lang) {
lang = $(âmeta[name:âdc.languageâ]').attr(âcontentâ)
}
...
110. let cheerio = require(âcheerio')
let cld = require('cld')
let getLang = (html, callback) => {
let $ = cheerio.load(html)
let lang = $('html[lang]').attr(âlang')
if (!lang) {
lang = $('html[xml:lang]').attr(âxml:langâ)
}
if (!lang) {
lang = $(âmeta[name:âdc.languageâ]').attr(âcontentâ)
}
...
111. let cheerio = require(âcheerio')
let cld = require('cld')
let getLang = (html, callback) => {
let $ = cheerio.load(html)
let lang = $('html[lang]').attr(âlang')
if (!lang) {
lang = $('html[xml:lang]').attr(âxml:langâ)
}
if (!lang) {
lang = $(âmeta[name:âdc.languageâ]').attr(âcontentâ)
}
...
112. let cheerio = require(âcheerio')
let cld = require('cld')
let getLang = (html, callback) => {
let $ = cheerio.load(html)
let lang = $('html[lang]').attr(âlang')
if (!lang) {
lang = $('html[xml:lang]').attr(âxml:langâ)
}
if (!lang) {
lang = $(âmeta[name:âdc.languageâ]').attr(âcontentâ)
}
...
114. let url = require(âurl')
let async = require(âasyncâ)
let icojs = require(âicojs')
let cheerio = require(âcheerio')
let request= require(ârequest')
let imgsize = require(âimage-size')
let imgtype = require(âimage-type')
let mime = require(â./mime-typesâ).lookup
let FilteType = require(âfile-type')
let flatten = require(âlodash/flattenDeep')
let filter = require(âlodash/filter')
let icons = (obj, callback) => {
let $ = cheerio.load(html)
let favicon = $(ârel[âshortcut iconâ]').attr(âhref')
137. if (âPaymentRequestâ in window) {
let payment = new PaymentRequest(methodData, details, options)
} else {
window.location.href = â/old-checkoutâ
}
This is what it looks like
Define a cache â you can have separate caches in SWs, one for blog content, another for comments, whatever
Listen for the install event
Prefetch our font, and anything else we know is guaranteed to want
Wait until our cache is opened up, then we request each and every one of those files and add them to our cache
This is what it looks like
Define a cache â you can have separate caches in SWs, one for blog content, another for comments, whatever
Listen for the install event
Prefetch our font, and anything else we know is guaranteed to want
Wait until our cache is opened up, then we request each and every one of those files and add them to our cache
This is what it looks like
Define a cache â you can have separate caches in SWs, one for blog content, another for comments, whatever
Listen for the install event
Prefetch our font, and anything else we know is guaranteed to want
Wait until our cache is opened up, then we request each and every one of those files and add them to our cache
This is what it looks like
Define a cache â you can have separate caches in SWs, one for blog content, another for comments, whatever
Listen for the install event
Prefetch our font, and anything else we know is guaranteed to want
Wait until our cache is opened up, then we request each and every one of those files and add them to our cache
This is what it looks like
Define a cache â you can have separate caches in SWs, one for blog content, another for comments, whatever
Listen for the install event
Prefetch our font, and anything else we know is guaranteed to want
Wait until our cache is opened up, then we request each and every one of those files and add them to our cache
This is what it looks like
Define a cache â you can have separate caches in SWs, one for blog content, another for comments, whatever
Listen for the install event
Prefetch our font, and anything else we know is guaranteed to want
Wait until our cache is opened up, then we request each and every one of those files and add them to our cache
After we do that, we set up listener for FETCH event
Every time anything on the site is requested from our domain, we see if it is in the cache
Got it? Give it
Donât? go get it
Instantaneous responses, even with dozens upon dozens of requests
After we do that, we set up listener for FETCH event
Every time anything on the site is requested from our domain, we see if it is in the cache
Got it? Give it
Donât? go get it
Instantaneous responses, even with dozens upon dozens of requests
After we do that, we set up listener for FETCH event
Every time anything on the site is requested from our domain, we see if it is in the cache
Got it? Give it
Donât? go get it
Instantaneous responses, even with dozens upon dozens of requests
It IS the future, but support is pretty meh
Which sucks, beause I want something today â not a year or three from now
If only we had something widely supported todayâŠ
I know what you are thinking
Appcache is a douchebag
Yes â it really is. It sucksin a lot of ways
SW are WAY better, except for support
SW are WAY better, except for support
And it covers our basic usage of instant cache reading
{{40% done â 20 minutes}}
Appcache is everywhere
Do basic namespace check
You put it in your head
You canât add it programmatically. It HAS to be there on load
Do basic namespace check
We just load it in ANOTHER page
Create iframe, load tiny page that is just the appcache manifest
We just load it in ANOTHER page
Create iframe, load tiny page that is just the appcache manifest
We just load it in ANOTHER page
Create iframe, load tiny page that is just the appcache manifest
We just load it in ANOTHER page
Create iframe, load tiny page that is just the appcache manifest
Appcache takes over domain
After initial load, firefox - NEXT
Appcache is manifest driven
Its just a big text file, with .appcache extension looks like this
Blob of text that lists files, and a few rules
Dunders are variables that we use to generate this file programatically
Cache version important to break cache â just date epoch
Assets is list of files to be added to the precache list
Appcache is manifest driven
Its just a big text file, with .appcache extension looks like this
Blob of text that lists files, and a few rules
Dunders are variables that we use to generate this file programatically
Cache version important to break cache â just date epoch
Assets is list of files to be added to the precache list
Appcache is manifest driven
Its just a big text file, with .appcache extension looks like this
Blob of text that lists files, and a few rules
Dunders are variables that we use to generate this file programatically
Cache version important to break cache â just date epoch
Assets is list of files to be added to the precache list
Appcache is manifest driven
Its just a big text file, with .appcache extension looks like this
Blob of text that lists files, and a few rules
Dunders are variables that we use to generate this file programatically
Cache version important to break cache â just date epoch
Assets is list of files to be added to the precache list
Appcache is a douchebag
Yes â it really is. It sucksin a lot of ways
Added to webkit ri in 2008
Chroem was in version 2!
Chroem was in version 2!
Chroem was in version 2!
Chroem was in version 2!
So what are they? It is a way to get around some browser limitations without breaking the web
Means browser can only do one thing at a time
Browser doesnât know you wonât change page in scroll loop,
So it has to execute code before it can paint the result of the scroll
Scroll handlers, runaway scripts, underpowred machinesâŠ
Crappy user expierence
Webworkers lets us take certain tasks, fence them off from the main thread of the browser, and have the browser opportunistically execute that code without effecting the pageâs painting
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Appcache takes over domain
After initial load, firefox - NEXT
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
Do basic namespace check
So what are they? It is a way to get around some browser limitations without breaking the web
So what are they? It is a way to get around some browser limitations without breaking the web
So what are they? It is a way to get around some browser limitations without breaking the web
So what are they? It is a way to get around some browser limitations without breaking the web
Added to webkit ri in 2008
Browserâs donât know everything, we just pretend to
Real world usage WILL change the spec. Be a part of it!
Browserâs donât know everything, we just pretend to
Real world usage WILL change the spec. Be a part of it!
Always try to push the experience one step further, and then another
I even had to do a lot of extra work to get it at microsoft
That is my acutal work email â LET ME HEAR FROM YOU!
Change the world