@@ -223,6 +223,252 @@ <h3>ES5 Namespace Pattern</h3>
223223 </ section >
224224
225225
226+
227+
228+
229+
230+ < section data-background-color ="var(--secondary-color) ">
231+ < h1 style ="font-size: 4.9em; margin-bottom: -0.25em; " class ="fallbackColor " > Offline</ h1 >
232+ < h1 style ="font-size: 4.5em; margin-bottom: -0.25em; " class ="primaryColor " > caching</ h1 >
233+ < h1 style ="font-size: 4.1em; "class ="flippedColor " > dilemma</ h1 >
234+ </ section >
235+
236+
237+ <!--http://alistapart.com/article/application-cache-is-a-douchebag-->
238+ < section >
239+ < h3 > AppCache lottery</ h3 >
240+ < ul class ="no-bullets ">
241+ < li > Files always come from cache</ li >
242+ < li > Application updates only on manifest content change</ li >
243+ < li > Additional not alternative cache</ li >
244+ < li > Non-cached resources do not load on cached page</ li >
245+ < li > lack of JavaScript API</ li >
246+ </ ul >
247+ </ section >
248+
249+
250+
251+ < section data-background-color ="var(--secondary-color) ">
252+ < h1 style ="font-size: 2.0em; margin-bottom: -0.25em; " class ="fallbackColor " > Service Workers</ h1 >
253+ < h1 style ="font-size: 2.3em; margin-bottom: -0.25em; " class ="primaryColor " > Return power</ h1 >
254+ < h1 style ="font-size: 2.7em; "class ="flippedColor " > to the devs!</ h1 >
255+ </ section >
256+
257+
258+ < section >
259+ < h3 > Service Workers</ h3 >
260+ < ul class ="no-bullets ">
261+ < li > Give developers the moving parts to solve their problems</ li >
262+ < li > Alow to create own caching patterns</ li >
263+ </ ul >
264+ </ section >
265+
266+
267+ < section data-background-color ="var(--secondary-color) ">
268+ < h1 style ="font-size: 2.4em; margin-bottom: 0em; " class ="fallbackColor " > Wait wait wait!</ h1 >
269+ < h1 style ="font-size: 1.95em; margin-bottom: -0.25em; " class ="primaryColor " > But what are those</ h1 >
270+ < h1 style ="font-size: 4em; "class ="flippedColor " > workers?</ h1 >
271+ </ section >
272+
273+
274+ <!--https://www.html5rocks.com/en/tutorials/workers/basics/-->
275+ < section >
276+ < h3 > Workers</ h3 >
277+ < ul class ="no-bullets ">
278+ < li > Isolated thread</ li >
279+ < li > Code contained in separate file (async download)</ li >
280+ < li > Communication via message passing - postMessage()</ li >
281+ < li > Messages copied, not shared</ li >
282+ < li > Same Origin</ li >
283+ </ ul >
284+ </ section >
285+
286+ < section >
287+ < h3 > Main script:</ h3 >
288+ < pre > < code class ="js " data-trim data-noescape >
289+ var worker = new Worker('task.js');
290+
291+ worker.addEventListener('message', function(e) {
292+ console.log('Worker said: ', e.data);
293+ }, false);
294+
295+ worker.addEventListener('error', function(e){
296+ console.log('ERROR: Line', e.lineno, 'in',
297+ e.filename, ':', e.message);
298+ }, false);
299+
300+ worker.postMessage('Hello World'); // Send data to our worker.
301+ </ code > </ pre >
302+
303+ < h3 > task.js (the worker)</ h3 >
304+ < pre > < code class ="js " data-trim data-noescape >
305+ self.addEventListener('message', function(e) {
306+ self.postMessage(e.data);
307+ }, false);
308+ </ code > </ pre >
309+ </ section >
310+
311+ < section >
312+ < h3 > Features Available to Workers</ h3 >
313+ < ul class ="no-bullets ">
314+ < li > The navigator object</ li >
315+ < li > The location object (read-only)</ li >
316+ < li > < XMLHttpRequest > </ XMLHttpRequest > </ li >
317+ < li > setTimeout()/clearTimeout() and setInterval()/clearInterval()</ li >
318+ < li > The Application Cache</ li >
319+ < li > Importing external scripts using the importScripts() method</ li >
320+ < li > Spawning other web workers</ li >
321+ </ ul >
322+ </ section >
323+
324+ < section >
325+ < h3 > Workers do NOT have access to:</ h3 >
326+ < ul class ="no-bullets ">
327+ < li > The DOM (it's not thread-safe)</ li >
328+ < li > The window object</ li >
329+ < li > The document object</ li >
330+ < li > The parent object</ li >
331+ < li > will not run locally (e.g. from file://)</ li >
332+ </ ul >
333+ </ section >
334+
335+ < section data-background-color ="var(--secondary-color) ">
336+ < h1 style ="font-size: 2em; margin-bottom: 0em; " class ="fallbackColor " > The</ h1 >
337+ < h1 style ="font-size: 2.5em; margin-bottom: 0em; " class ="primaryColor " > cache</ h1 >
338+ < h1 style ="font-size: 3em; "class ="flippedColor " > machine</ h1 >
339+ </ section >
340+
341+ <!--https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/-->
342+ < section >
343+ < h3 > On install - as a dependency</ h3 >
344+ < img class ="plain " style ="max-height: 12em; " src ="/src/img/cm-on-install-dep.png ">
345+ </ section >
346+
347+
348+ < section >
349+ < h3 > On install - as a dependency</ h3 >
350+ < pre > < code class ="js " data-trim data-noescape >
351+ self.addEventListener('install', function(event) {
352+ event.waitUntil(
353+ caches.open('mysite-static-v3').then(function(cache) {
354+ return cache.addAll([
355+ '/css/whatever-v3.css',
356+ '/css/imgs/sprites-v6.png',
357+ '/css/fonts/whatever-v8.woff',
358+ '/js/all-min-v4.js'
359+ // etc
360+ ]);
361+ })
362+ );
363+ });
364+ </ code > </ pre >
365+ </ section >
366+
367+ < section >
368+ < h3 > On install - not as a dependency</ h3 >
369+ < img class ="plain " style ="max-height: 12em; " src ="/src/img/cm-on-install-not.png ">
370+ </ section >
371+
372+
373+ < section >
374+ < h3 > On install - not as a dependency</ h3 >
375+ < pre > < code class ="js " data-trim data-noescape >
376+ self.addEventListener('install', function(event) {
377+ event.waitUntil(
378+ caches.open('mygame-core-v1').then(function(cache) {
379+ cache.addAll(
380+ // levels 11-20
381+ );
382+ return cache.addAll(
383+ // core assets & levels 1-10
384+ );
385+ })
386+ );
387+ });
388+ </ code > </ pre >
389+ </ section >
390+
391+
392+ < section >
393+ < h3 > On activate - cleanup</ h3 >
394+ < img class ="plain " style ="max-height: 12em; " src ="/src/img/cm-on-activate.png ">
395+ </ section >
396+
397+
398+ < section >
399+ < h3 > On activate - cleanup</ h3 >
400+ < pre > < code class ="js " data-trim data-noescape >
401+ self.addEventListener('activate', function(event) {
402+ event.waitUntil(
403+ caches.keys().then(function(cacheNames) {
404+ return Promise.all(
405+ cacheNames.filter(function(cacheName) {
406+ // Return true if you want to remove this cache,
407+ // but remember that caches are shared across
408+ // the whole origin
409+ }).map(function(cacheName) {
410+ return caches.delete(cacheName);
411+ })
412+ );
413+ })
414+ );
415+ });
416+ </ code > </ pre >
417+ </ section >
418+
419+
420+ < section >
421+ < h3 > On user interaction</ h3 >
422+ < img class ="plain " style ="max-height: 12em; " src ="/src/img/cm-on-user-interaction.png ">
423+ </ section >
424+
425+
426+ < section >
427+ < h3 > On user interaction</ h3 >
428+ < pre > < code class ="js " data-trim data-noescape >
429+ document.querySelector('.cache-article').addEventListener('click', function(event) {
430+ event.preventDefault();
431+
432+ var id = this.dataset.articleId;
433+ caches.open('mysite-article-' + id).then(function(cache) {
434+ fetch('/get-article-urls?id=' + id).then(function(response) {
435+ // /get-article-urls returns a JSON-encoded array of
436+ // resource URLs that a given article depends on
437+ return response.json();
438+ }).then(function(urls) {
439+ cache.addAll(urls);
440+ });
441+ });
442+ });
443+ </ code > </ pre >
444+ </ section >
445+
446+
447+ < section >
448+ < h1 > And more ...</ h1 >
449+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/cm-on-network-response.png ">
450+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/cm-stale-while-revalidate.png ">
451+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/cm-on-push.png ">
452+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/cm-on-bg-sync.png ">
453+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-cache-only.png ">
454+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-network-only.png ">
455+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-falling-back-to-network.png ">
456+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-cache-and-network-race.png ">
457+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-network-falling-back-to-cache.png ">
458+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-cache-then-network.png ">
459+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-generic-fallback.png ">
460+ < img class ="plain " style ="max-height: 2.4em; " src ="/src/img/ss-sw-side-templating.png ">
461+ </ section >
462+
463+
464+ < section data-background-iframe ="https://jakearchibald.github.io/isserviceworkerready/ ">
465+ < h1 style ="font-size: 3.0em; " class ="fallbackColor " > Can we use < a href ="https://jakearchibald.github.io/isserviceworkerready/ "> it</ a > ?</ h1 >
466+ </ section >
467+
468+
469+
470+
471+
226472 </ div >
227473 </ div >
228474
0 commit comments