Takingweb appsoffline                        pedro@morais.it                          @pedromoraisGDG Portugal DevFest   mor...
Offline webapps - why? no network connection required faster startup keep data local
The Road to Offline    user data     assets
1. user data
localStorage    *and sessionStorage
localstorage              Simple APIwindow.localStorage[‘hello’] = ‘world’;
localStorage       Can store a JSON stringwindow.localStorage[‘helloJSON’] = JSON.stringify({‘key1’: ‘world’,       ‘key2’...
92.25%   http://caniuse.com/indexeddb
localStorage limitations           Storage Limits            Spec - 5 Mb        Firefox - can adjusted  Chrome - 2600k cha...
localStorage limitations              Sync API   window.localStorage[‘sloooow’] =     ‘imagine a 1 MB string here’;
sql storage
sql storage     work stopped November ’10 sqlite was used in all implementations            (webkit, opera)mozilla & micro...
48.32%   http://caniuse.com/sql-storage
sql storagehttp://nparashuram.com/IndexedDBShim/    indexed db polyfill over websql
indexed db
indexed db                     Async APIvar request = indexedDB.doStuff();request.onerror = function(event) { ...};request...
indexed db               Opening a databasevar request = indexedDB.open("MyTestDatabase");request.onerror = ...var db;requ...
creating the schemavar request = indexedDB.open("MyTestDatabase", 5);...request.onupgradeneeded = function(event) { var db...
creating the schema# student: cardNumber, name, email, ...request.onupgradeneeded = function(event) { var db = event.targe...
adding datavar transaction     = db.transaction(["students"], "readwrite");transaction.oncomplete = function(event) {  ale...
adding data...var objectStore = transaction.objectStore("customers");aStudent = { ‘studentCard’: ‘44124’,             ‘nam...
updating data...var objectStore = transaction.objectStore("customers");aStudent = { ‘studentCard’: ‘44124’,             ‘n...
deleting data...var objectStore = transaction.objectStore("customers");var request = objectStore.delete(‘44124’);request.o...
getting datavar transaction = db.transaction(["students"]);var objectStore = transaction.objectStore("customers");var requ...
using a cursor....var request = objectStore.openCursor();request.onsuccess = function(event) {     var c = event.target.re...
using an index...var index = objectStore.index("name");index.get("Pedro Morais").onsuccess = function(event) {  console.lo...
using an index + cursor...var index = objectStore.index("name");var request     = index.openCursor(IDBKeyRange.only("Pedro...
cursor key rangesIDBKeyRange.only("Pedro Morais")IDBKeyRange.lowerBound("Pedro")IDBKeyRange.lowerBound("Pedro", true) // d...
46.93%   http://caniuse.com/indexeddb
2. assets
offline web apps
67.43%   http://caniuse.com/offline-apps
offline web apps<!DOCTYPE html><html manifest=”cache.appcache”>...  cache.appcache must be served as       text/cache-manifest
cache manifestCACHE MANIFEST# this is a commentcss/styles.cssjs/scripts.jsimages/logo.pngNETWORK:*
cache with fallbackCACHE MANIFEST# this is a commentcss/styles.cssjs/scripts.jsimages/logo.pngFALLBACK:/ /offline.htmlNETW...
network access                    not using appcache• user navigates to http://test.com/app.html• browser check if file “ap...
network access                       using appcache• user navigates to http://test.com/app.html• browser renders app.html ...
cache manifest versions CACHE MANIFEST # version 50 css/styles.css js/scripts.js images/logo.png NETWORK: *
cache manifest versions CACHE MANIFEST css/styles.css?b3c4de js/scripts.js?adf341 images/logo.png?ef3451 NETWORK: *       ...
cache manifest versions CACHE MANIFEST b3c4de/css/styles.css adf341/js/scripts.js ef3451/images/logo.png NETWORK: *       ...
conclusion
Available today   localStorage Indexed DB (+ polyfill)    AppCacheTake your web apps offline
Thanks!                        pedro@morais.it                          @pedromoraisGDG Portugal DevFest   morais on app.n...
Upcoming SlideShare
Loading in...5
×

Taking Web Apps Offline

1,537

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,537
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Taking Web Apps Offline

  1. 1. Takingweb appsoffline pedro@morais.it @pedromoraisGDG Portugal DevFest morais on app.net March ’13
  2. 2. Offline webapps - why? no network connection required faster startup keep data local
  3. 3. The Road to Offline user data assets
  4. 4. 1. user data
  5. 5. localStorage *and sessionStorage
  6. 6. localstorage Simple APIwindow.localStorage[‘hello’] = ‘world’;
  7. 7. localStorage Can store a JSON stringwindow.localStorage[‘helloJSON’] = JSON.stringify({‘key1’: ‘world’, ‘key2’: ‘Lisbon’});
  8. 8. 92.25% http://caniuse.com/indexeddb
  9. 9. localStorage limitations Storage Limits Spec - 5 Mb Firefox - can adjusted Chrome - 2600k chars (5 mb in UTF-16) IE - 5000k chars
  10. 10. localStorage limitations Sync API window.localStorage[‘sloooow’] = ‘imagine a 1 MB string here’;
  11. 11. sql storage
  12. 12. sql storage work stopped November ’10 sqlite was used in all implementations (webkit, opera)mozilla & microsoft: “not gonna happen”
  13. 13. 48.32% http://caniuse.com/sql-storage
  14. 14. sql storagehttp://nparashuram.com/IndexedDBShim/ indexed db polyfill over websql
  15. 15. indexed db
  16. 16. indexed db Async APIvar request = indexedDB.doStuff();request.onerror = function(event) { ...};request.onsuccess = function(event) { ...};
  17. 17. indexed db Opening a databasevar request = indexedDB.open("MyTestDatabase");request.onerror = ...var db;request.onsuccess = function(event) { db = request.result;};
  18. 18. creating the schemavar request = indexedDB.open("MyTestDatabase", 5);...request.onupgradeneeded = function(event) { var db = event.target.result; ...};
  19. 19. creating the schema# student: cardNumber, name, email, ...request.onupgradeneeded = function(event) { var db = event.target.result; var studentsStore = db.createObjectStore("students", { keyPath: "cardNumber" }); studentsStore.createIndex("nameIndex", "name", { unique: false }); studentsStore.createIndex("emailIndex", "email", { unique: true });};
  20. 20. adding datavar transaction = db.transaction(["students"], "readwrite");transaction.oncomplete = function(event) {  alert("All done!");};...// transactions go away when you// return to the event loop// without making a request
  21. 21. adding data...var objectStore = transaction.objectStore("customers");aStudent = { ‘studentCard’: ‘44124’, ‘name’: ‘Pedro Morais’, ‘email’: ‘pedro@morais.it}var request = objectStore.add(aStudent);request.onsuccess = function(event) {  // event.target.result == aStuddent.studentCard};
  22. 22. updating data...var objectStore = transaction.objectStore("customers");aStudent = { ‘studentCard’: ‘44124’, ‘name’: ‘Pedro Morais with updated name’, ‘email’: ‘pedro@morais.it}var request = objectStore.put(aStudent);request.onsuccess = function(event) {  // event.target.result == aStuddent.studentCard};
  23. 23. deleting data...var objectStore = transaction.objectStore("customers");var request = objectStore.delete(‘44124’);request.onsuccess = function(event) { // deleted};
  24. 24. getting datavar transaction = db.transaction(["students"]);var objectStore = transaction.objectStore("customers");var request = objectStore.get(‘44124’);request.onsuccess = function(event) { console.log(“Name is “, request.result.name);};
  25. 25. using a cursor....var request = objectStore.openCursor();request.onsuccess = function(event) { var c = event.target.result;  if (c) {    console.log ("Student " + c + " is named " + c.value.name);    cursor.continue();  } else {    console.log("Done!");  }};
  26. 26. using an index...var index = objectStore.index("name");index.get("Pedro Morais").onsuccess = function(event) {  console.log("Email=" + event.target.result.email);};// if name is not unique// you get the first entry that matches
  27. 27. using an index + cursor...var index = objectStore.index("name");var request = index.openCursor(IDBKeyRange.only("Pedro Morais"));request.onsuccess = function(event) {  var c = event.target.result;  if (c) {    // c.key is a name, like "Pedro Morais", // c.value is the whole object.    console.log("Name: " + cursor.key + “Email: " + cursor.value.email);    cursor.continue();  }};
  28. 28. cursor key rangesIDBKeyRange.only("Pedro Morais")IDBKeyRange.lowerBound("Pedro")IDBKeyRange.lowerBound("Pedro", true) // don’t inc PedroIDBKeyRange.upperBound("Pedro", true) // don’t inc PedroIDBKeyRange.bound("Pedro", "Vanda", false, true);// include Pedro, don’t include Vanda
  29. 29. 46.93% http://caniuse.com/indexeddb
  30. 30. 2. assets
  31. 31. offline web apps
  32. 32. 67.43% http://caniuse.com/offline-apps
  33. 33. offline web apps<!DOCTYPE html><html manifest=”cache.appcache”>... cache.appcache must be served as text/cache-manifest
  34. 34. cache manifestCACHE MANIFEST# this is a commentcss/styles.cssjs/scripts.jsimages/logo.pngNETWORK:*
  35. 35. cache with fallbackCACHE MANIFEST# this is a commentcss/styles.cssjs/scripts.jsimages/logo.pngFALLBACK:/ /offline.htmlNETWORK:*
  36. 36. network access not using appcache• user navigates to http://test.com/app.html• browser check if file “app.html” is in cache• browser check if it has not expired• browser checks validity of file using etags (optional)• browser renders the cached or downloaded app.html
  37. 37. network access using appcache• user navigates to http://test.com/app.html• browser renders app.html from appcache• in the background: • browser checks if manifest has changed • if it has, browser downloads all files in the manifest (expires, etags still apply) • user only gets new version of app.html the next time!
  38. 38. cache manifest versions CACHE MANIFEST # version 50 css/styles.css js/scripts.js images/logo.png NETWORK: *
  39. 39. cache manifest versions CACHE MANIFEST css/styles.css?b3c4de js/scripts.js?adf341 images/logo.png?ef3451 NETWORK: * + far future expires
  40. 40. cache manifest versions CACHE MANIFEST b3c4de/css/styles.css adf341/js/scripts.js ef3451/images/logo.png NETWORK: * + far future expires
  41. 41. conclusion
  42. 42. Available today localStorage Indexed DB (+ polyfill) AppCacheTake your web apps offline
  43. 43. Thanks! pedro@morais.it @pedromoraisGDG Portugal DevFest morais on app.net March ’13
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×