Slide 1

Slide 1 text

Taking the Web Offline Erik Runyon @erunyon #AIM10 October 2014

Slide 2

Slide 2 text

Erik Runyon Director of Web Communications The University of Notre Dame @erunyon weedygarden.net #AIM10

Slide 3

Slide 3 text

Today’s Topics I. Why? II. The Past III. The Future

Slide 4

Slide 4 text

I. Why?

Slide 5

Slide 5 text

Erik’s personal Bermuda Triangle of AT&T (and Sprint) suckage

Slide 6

Slide 6 text

Service * not a true story Service Unavailable

Slide 7

Slide 7 text

Service REALLY Unavailable

Slide 8

Slide 8 text

Speed!!!!

Slide 9

Slide 9 text

We want an app…

Slide 10

Slide 10 text

II. The Past

Slide 11

Slide 11 text

Cookies • Introduced in 1994 by the Netscape Communications Corporation • Data passed to the server • Store up to 4KB per cookie

Slide 12

Slide 12 text

Less notable solutions Flash “Cookies” (Local Shared Objects) 100KB Google Gears (deprecated in 2011)

Slide 13

Slide 13 text

Where we’re going, we don’t need… reliable internet connections. III. The Future

Slide 14

Slide 14 text

Web SQL Database

Slide 15

Slide 15 text

Wrapper around SQLite http://www.w3.org/TR/webdatabase/ SQLite is an in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine.

Slide 16

Slide 16 text

Chrome Android Safari iOS Firefox IE 4+ 2.1+ 3.1+ 3.2+ None None* Web SQL Support * Not currently planned (status.modern.ie)

Slide 17

Slide 17 text

The nail in the coffin… Spec is no longer in active maintenance.

Slide 18

Slide 18 text

IndexedDB

Slide 19

Slide 19 text

What it is… IndexedDB is a client side storage API that persists data in a user's browser. It is a transactional, non-relational storage mechanism that saves key-value pairs in Object Stores and allows searching data using indexes. http://docs.webplatform.org/wiki/apis/indexedDB

Slide 20

Slide 20 text

What it’s not… IndexedDB is NOT a Relational Database http://docs.webplatform.org/wiki/apis/indexedDB

Slide 21

Slide 21 text

Chrome Android Safari iOS Firefox IE 23+ 4.4+ 8 8 10+ 10+* IndexedDB Support * a number of sub features are not supported in IE 10 & 11

Slide 22

Slide 22 text

Opening // Opening a Database var db; var request = window.indexedDB.open("HEWeb 2014 Presentations", 1); request.onerror = function(event) { console.log("Database error: " + event.target.errorCode); }; request.onupgradeneeded = function(event){ console.log("Upgrading"); db = event.target.result; var objectStore = db.createObjectStore("presentations", { keyPath : "uniq_id" }); }; request.onsuccess = function(event){ console.log("Success opening DB"); db = event.target.result; };

Slide 23

Slide 23 text

Adding // Adding an object var uniq_id = "4cb507e9-56c5-478b-9ba6-87f4e509db38"; var title = "Taking the web offline"; var transaction = db.transaction(["presentations"],"readwrite"); var objectStore = transaction.objectStore("presentations"); objectStore.add({uniq_id: uniq_id, title: title});

Slide 24

Slide 24 text

Deleting var uniq_id = "4cb507e9-56c5-478b-9ba6-87f4e509db38"; // Removing Object from ObjectStore var transaction = db.transaction(["presentations"],"readwrite"); transaction.objectStore("presentations").delete(uniq_id);

Slide 25

Slide 25 text

Accessing an object var uniq_id = "4cb507e9-56c5-478b-9ba6-87f4e509db38"; // Accessing an object with the key var transaction = db.transaction(["presentations"],"readwrite"); var request = transaction.objectStore("presentations").get(uniq_id); request.onsuccess = function(event){ console.log("Title : " + request.result.title); };

Slide 26

Slide 26 text

Updating // Updating an Object var uniq_id = "4cb507e9-56c5-478b-9ba6-87f4e509db38"; var transaction = db.transaction(["presentations"],"readwrite"); var objectStore = transaction.objectStore("presentations").get(uniq_id); var request = objectStore.get(uniq_id); request.onsuccess = function(event){ request.result.title = "Taking the web… ! offline. YEAHHHHH!!!!"; objectStore.put(request.result); };

Slide 27

Slide 27 text

Combining IndexedDB and Web SQL? • git.yathit.com/ydn-db/wiki/Home • github.com/axemclion/IndexedDBShim • github.com/mozilla/localForage

Slide 28

Slide 28 text

Chrome Android Safari iOS Firefox IE 4+ 2.1+ 3.1+ 3.2+ 10+ 10+ IndexedDB + Web SQL

Slide 29

Slide 29 text

Summary Use indexedDB to store large sets of data that needs to be searchable.

Slide 30

Slide 30 text

Web Storage

Slide 31

Slide 31 text

What it is… The Web Storage API provides objects for storing temporary (sessionStorage) and permanent (localStorage) data on the client's device. http://docs.webplatform.org/wiki/apis/web-storage

Slide 32

Slide 32 text

Chrome Android Safari iOS Firefox IE 4+ 2.1+ 4+ 3.2+ 3.5+ 8+ Support

Slide 33

Slide 33 text

Session Storage Stores data for current session and browser tab only. sessionStorage Provides a Storage object for an origin, that remains persistent even after restarting the browser. localStorage Local Storage

Slide 34

Slide 34 text

Testing Support Vanilla javascript: if(window.localStorage !== undefined){ // window.localStorage is available! } Using Modernizr: if(Modernizr.localstorage){ // window.localStorage is available! }

Slide 35

Slide 35 text

Syntax // Setting localStorage.setItem("foo", "Bar"); localStorage["foo"] = "Bar"; localStorage.foo = "Bar" // Getting localStorage.getItem("foo"); localStorage["foo"]; localStorage.foo;

Slide 36

Slide 36 text

Syntax localStorage.setItem("foo", "Bar"); localStorage.getItem("foo"); // Removing an item localStorage.removeItem("foo"); // Clearing storage localStorage.clear();

Slide 37

Slide 37 text

Storing Data: numbers localStorage.setItem("foo", 500); > localStorage.getItem("foo"); > "500" > ParseInt(localStorage.getItem("foo"), 10); > 500

Slide 38

Slide 38 text

Storing Data: objects/arrays var my_array = ["foo", "bar", "baz"]; localStorage.setItem("bar", JSON.stringify(my_array)); var my_stored_array = JSON.parse(localStorage.getItem("bar"));

Slide 39

Slide 39 text

http://www.html5rocks.com/en/tutorials/offline/quota-research/ Chrome Android Safari iOS Firefox IE 10MB 10MB 5MB 5MB 10MB 10MB Storage Limits

Slide 40

Slide 40 text

Chrome Inspector

Slide 41

Slide 41 text

2014.heweb.org Editing the schedule

Slide 42

Slide 42 text

  • Taking the Web Offline

    Presenters

    • Erik Runyon - University of Notre Dame
    Blah blah blah

    Tags

    View Details
    Add
  • Slide 43

    Slide 43 text

    Adding/Removing var schedule = JSON.parse(localStorage.getItem("schedule")) || []; // As buttons are clicked // sid is the pulled from the “data-id” if($.inArray(sid, schedule) == -1){ schedule.push(sid); } else { var indexId = $.inArray(sid, schedule); schedule.splice(indexId, 1); } localStorage.setItem("schedule", JSON.stringify(schedule));

    Slide 44

    Slide 44 text

    foo.on("click", ".sch-academies", function(e){ e.preventDefault(); if(localStorage.getItem("hideAcademies") == "true"){ localStorage.removeItem("hideAcademies"); $(".section-academies").show(); $(this).html("Hide Academies"); } else { localStorage.setItem("hideAcademies", "true"); $(".section-academies").hide(); $(this).html("Show Academies"); } }) Workshops and Academies

    Slide 45

    Slide 45 text

    foo.on("click", ".sch-academies", function(e){ e.preventDefault(); if(localStorage.getItem("hideAcademies") == "you_betcha"){ localStorage.removeItem("hideAcademies"); $(".section-academies").show(); $(this).html("Hide Academies"); } else { localStorage.setItem("hideAcademies", "you_betcha"); $(".section-academies").hide(); $(this).html("Show Academies"); } }); Workshops and Academies

    Slide 46

    Slide 46 text

    Items of note • Clearing a browsers cache does NOT clear web storage • There is no built-in way to expire web storage • Data is scoped to the domain

    Slide 47

    Slide 47 text

    Summary Use localStorage to quickly and easily store small amounts of data.

    Slide 48

    Slide 48 text

    Appcache

    Slide 49

    Slide 49 text

    What it is… Application Cache provides a manifest which lists the files that are needed for the Web application to work offline and which causes the user's browser to keep a copy of the files for use offline. http://docs.webplatform.org/wiki/apis/appcache

    Slide 50

    Slide 50 text

    " #

    Slide 51

    Slide 51 text

    Chrome Android Safari iOS Firefox IE 4+ 2.1+ 4+ 3.2+ 3.5+ 10+ Support

    Slide 52

    Slide 52 text

    http://alistapart.com/article/application-cache-is-a-douchebag

    Slide 53

    Slide 53 text

    Getting started…

    Slide 54

    Slide 54 text

    mime-type # Apache AddType text/cache-manifest .appcache # .NET

    Slide 55

    Slide 55 text

    Prevent appcache Caching # Apache ExpiresActive On ExpiresByType text/cache-manifest "access plus 0 seconds" # .NET

    Slide 56

    Slide 56 text

    Markup

    Slide 57

    Slide 57 text

    The manifest CACHE MANIFEST /foo/ stylesheet.css images/logo.png scripts/main.js http://cdn.example.com/scripts/main.js

    Slide 58

    Slide 58 text

    Ok, so it’s not quite THAT easy.

    Slide 59

    Slide 59 text

    Notes on Domains • Resources do NOT have to be on the same domain to be cached. • Over SSL, all resources in the manifest must respect the same-origin policy (except in Chrome).

    Slide 60

    Slide 60 text

    Basic Structure CACHE MANIFEST # v2014.10.21.0 CACHE: /css/site.css NETWORK: * FALLBACK: /file.php /static.html /images/ /images/offline.png Required at the beginning of the file Instructions for requested files/paths that are not cached List of explicit URLs to be stored locally Resources only available while online

    Slide 61

    Slide 61 text

    The order of things 1. Browser visits site for the first time, site is downloaded 2. Manifest is read and all files are saved for offline use 3. Visitor returns to site and appcache serves page and assets from the cache (even if user is online) 4. Browser then checks for updated manifest 5. If update is found, appcache refreshes outdated files/assets 6. On next visit/refresh, the browser shows the most recent version

    Slide 62

    Slide 62 text

    Items of note • The referencing file will ALWAYS be cached • The file referencing the manifest can’t be NETWORK whitelisted • The manifest file must be updated for changes to be sent • If any files specified in the manifest cannot be found, the entire cache will be ignored • Cached files are always served from appcache, even when online

    Slide 63

    Slide 63 text

    Fonts Include as few fonts as possible

    Slide 64

    Slide 64 text

    Google Fonts Referenced: @import url(http://fonts.googleapis.com/css?family=Montserrat); @import url(http://fonts.googleapis.com/css?family=Indie+Flower); Downloaded: http://fonts.gstatic.com/s/montserrat/v6/zhcz-_WihjSQC0oHJ9TCYAsYbbCjybiHxArTLjt7FRU.woff2 http://fonts.gstatic.com/s/indieflower/v7/10JVD_humAd5zP2yrFqw6hVuXpl7XtNjpLlhhhGlVqc.woff2

    Slide 65

    Slide 65 text

    Chrome Android Safari iOS Firefox IE 5+ 4.4+ 5.1+ 5.1+ 3.6+ 9+ WOFF Support (86.6% U.S.A.) http://caniuse.com/#feat=woff

    Slide 66

    Slide 66 text

    The javascript side of appcache

    Slide 67

    Slide 67 text

    Javascript Events updateready // Fired when the manifest resources have been newly re-downloaded progress // Fired for each resource listed in the manifest as it is being fetched checking // Checking for an update. Always the first event fired in the sequence downloading // An update was found. The browser is fetching resources cached // Fired after the first cache of the manifest noupdate // Fired after the first download of the manifest obsolete // This results in the application cache being deleted error // The manifest returns 404 or 410, the download failed, or the manifest changed while the download was in progress

    Slide 68

    Slide 68 text

    Forcing an update // Check for updated version of appcache window.addEventListener('load', function(e) { if(window.applicationCache) { var appCache = window.applicationCache; appCache.addEventListener('updateready', function(e) { if(appCache.status == appCache.UPDATEREADY) { if(confirm('A new version of this site is available. Load it?')) { window.location.reload(); } } }, false); } }, false);

    Slide 69

    Slide 69 text

    http://www.html5rocks.com/en/tutorials/offline/quota-research/ Chrome Android Safari iOS Firefox IE Unlimited 20MB? Unlimited 10MB Unlimited 10MB Storage Limits *Big Frickin Asterisk

    Slide 70

    Slide 70 text

    Chrome Storage Limits Sharing the pool Temporary storage is shared among all web apps running in the browser. The shared pool can be up to half of the of available disk space. Storage already used by apps is included in the calculation of the shared pool; that is to say, the calculation is based on (available storage space + storage being used by apps) * .5 . Each app can have up to 20% of the shared pool. As an example, if the total available disk space is 50 GB, the shared pool is 25 GB, and the app can have up to 5 GB. This is calculated from 20% of half of the available disk space. https://developers.google.com/chrome/whitepapers/storage

    Slide 71

    Slide 71 text

    Chrome Storage Limits Running out of storage Once the storage quota for the entire pool is exceeded, the entire data stored for the least recently used host gets deleted. The browser, however, will not expunge the data in LocalStorage and SessionStorage. For data stored in other offline APIs, the browser deletes the data in whole and not in part so that app data doesn't get corrupted in unexpected ways. As each app is limited to a maximum of 20% of the storage pool, deletion is likely only if the user is actively running more than five offline apps that are each using the maximum storage. However, available storage space can shrink as users add more files on their hard drives. When the available disk space gets tight (Remember, the shared pool only gets half of the current available disk space), the browser deletes all the data stored for the least recently used host. https://developers.google.com/chrome/whitepapers/storage

    Slide 72

    Slide 72 text

    http://www.html5rocks.com/en/tutorials/offline/quota-research/ Chrome Android Safari iOS Firefox IE It depends It depends It depends It depends It depends It depends Storage Limits

    Slide 73

    Slide 73 text

    Example gameday.nd.edu/countdown

    Slide 74

    Slide 74 text

    CACHE MANIFEST # v2014.10.10.1 CACHE: app.css app.js http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js images/cd-clock-labels.png images/cd-header-repeat.png images/[email protected] images/cd-wrapper.jpg images/[email protected] images/digits.gif images/gameday-icon.png images/helmet-arizona-state.png images/helmet-florida-state.png images/helmet-louisville.png images/helmet-michigan.png images/helmet-navy.png images/helmet-north-carolina.png images/helmet-northwestern.png images/helmet-purdue.png images/helmet-rice.png images/helmet-stanford.png images/helmet-syracuse.png images/helmet-usc.png images/nbc.gif images/wrapper.jpg NETWORK: *

    Slide 75

    Slide 75 text

    Download Progress

    Slide 76

    Slide 76 text

    Chrome Inspector chrome://appcache-internals/

    Slide 77

    Slide 77 text

    Clearing appcache chrome://appcache-internals/

    Slide 78

    Slide 78 text

    Example 2014.highedweb.org

    Slide 79

    Slide 79 text

    Why? Instead of several “native” mobile apps, the conference committee decided to focus on an offline capable responsive website. Because conference wifi.

    Slide 80

    Slide 80 text

    / /about/ /attendees/ /schedule/ /events/ /venue/ /sponsors/ /gunn/ /hardwick/ The pages

    Slide 81

    Slide 81 text

    / /images/2014/gunn-home.jpg /images/2014/hardwick-home.jpg /about/ /images/2014/attendees.jpg /attendees/ /images/2014/registration.jpg /schedule/ /events/ /images/2014/afterdark.jpg /images/2014/hackathon.jpg The pages

    Slide 82

    Slide 82 text

    /sponsors/logos/acquia.png /sponsors/logos/active-data.png /sponsors/logos/barkley-rei.png /sponsors/logos/beacon.png /sponsors/logos/c2.png /sponsors/logos/caktus.png /sponsors/logos/campus-bird.png /sponsors/logos/campusm.png /sponsors/logos/campuspress.png /sponsors/logos/expertfile.png /sponsors/logos/form-assembly.png The images 28 Images? Nope, sorry

    Slide 83

    Slide 83 text

    /styles/site.css /styles/schedule.css /styles/fonts/Arvo-Regular.woff /styles/fonts/Arvo-Bold.woff /scripts/modernizr.js /scripts/jquery-2.1.0.min.js /scripts/2014.js The support staff

    Slide 84

    Slide 84 text

    FALLBACK: /page-with-a-form/ /offline/forms/ / /offline/ Fallback pages

    Slide 85

    Slide 85 text

    if(appCache.status == appCache.UPDATEREADY) { $('#site-reload').slideToggle(); } Non-obtrusive updating

    Slide 86

    Slide 86 text

    IV. Wrapping Up

    Slide 87

    Slide 87 text

    IndexedDB For large sets of searchable data.

    Slide 88

    Slide 88 text

    Web Storage For small data sets (articles/settings) that don’t necessarily need to be passed to the server on every request.

    Slide 89

    Slide 89 text

    Appcache Store site/data for offline use.

    Slide 90

    Slide 90 text

    Find a reason to play with new web technology.

    Slide 91

    Slide 91 text

    Credits Offline phone graphic: @tpacket Browser logos: https://github.com/alrra/browser-logos Photos: Subway: https://www.flickr.com/photos/kenstein/2313111565 Notre Dame Stadium: Matt Cashore - photos.nd.edu Cat: https://www.flickr.com/photos/77654185@N07/9029847786

    Slide 92

    Slide 92 text

    Erik Runyon @erunyon weedygarden.net bit.ly/hew2014 thank you