Taking Web Apps Offline
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Taking Web Apps Offline

on

  • 1,161 views

 

Statistics

Views

Total Views
1,161
Views on SlideShare
667
Embed Views
494

Actions

Likes
0
Downloads
6
Comments
0

4 Embeds 494

http://morais.it 491
http://www.bing.com 1
https://twitter.com 1
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Taking Web Apps Offline Presentation Transcript

  • 1. Takingweb appsoffline pedro@morais.it @pedromoraisGDG Portugal DevFest morais on app.net March ’13
  • 2. Offline webapps - why? no network connection required faster startup keep data local
  • 3. The Road to Offline user data assets
  • 4. 1. user data
  • 5. localStorage *and sessionStorage
  • 6. localstorage Simple APIwindow.localStorage[‘hello’] = ‘world’;
  • 7. localStorage Can store a JSON stringwindow.localStorage[‘helloJSON’] = JSON.stringify({‘key1’: ‘world’, ‘key2’: ‘Lisbon’});
  • 8. 92.25% http://caniuse.com/indexeddb
  • 9. localStorage limitations Storage Limits Spec - 5 Mb Firefox - can adjusted Chrome - 2600k chars (5 mb in UTF-16) IE - 5000k chars
  • 10. localStorage limitations Sync API window.localStorage[‘sloooow’] = ‘imagine a 1 MB string here’;
  • 11. sql storage
  • 12. sql storage work stopped November ’10 sqlite was used in all implementations (webkit, opera)mozilla & microsoft: “not gonna happen”
  • 13. 48.32% http://caniuse.com/sql-storage
  • 14. sql storagehttp://nparashuram.com/IndexedDBShim/ indexed db polyfill over websql
  • 15. indexed db
  • 16. indexed db Async APIvar request = indexedDB.doStuff();request.onerror = function(event) { ...};request.onsuccess = function(event) { ...};
  • 17. indexed db Opening a databasevar request = indexedDB.open("MyTestDatabase");request.onerror = ...var db;request.onsuccess = function(event) { db = request.result;};
  • 18. creating the schemavar request = indexedDB.open("MyTestDatabase", 5);...request.onupgradeneeded = function(event) { var db = event.target.result; ...};
  • 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. 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. 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. 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. deleting data...var objectStore = transaction.objectStore("customers");var request = objectStore.delete(‘44124’);request.onsuccess = function(event) { // deleted};
  • 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. 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. 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. 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. 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. 46.93% http://caniuse.com/indexeddb
  • 30. 2. assets
  • 31. offline web apps
  • 32. 67.43% http://caniuse.com/offline-apps
  • 33. offline web apps<!DOCTYPE html><html manifest=”cache.appcache”>... cache.appcache must be served as text/cache-manifest
  • 34. cache manifestCACHE MANIFEST# this is a commentcss/styles.cssjs/scripts.jsimages/logo.pngNETWORK:*
  • 35. cache with fallbackCACHE MANIFEST# this is a commentcss/styles.cssjs/scripts.jsimages/logo.pngFALLBACK:/ /offline.htmlNETWORK:*
  • 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. 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. cache manifest versions CACHE MANIFEST # version 50 css/styles.css js/scripts.js images/logo.png NETWORK: *
  • 39. cache manifest versions CACHE MANIFEST css/styles.css?b3c4de js/scripts.js?adf341 images/logo.png?ef3451 NETWORK: * + far future expires
  • 40. cache manifest versions CACHE MANIFEST b3c4de/css/styles.css adf341/js/scripts.js ef3451/images/logo.png NETWORK: * + far future expires
  • 41. conclusion
  • 42. Available today localStorage Indexed DB (+ polyfill) AppCacheTake your web apps offline
  • 43. Thanks! pedro@morais.it @pedromoraisGDG Portugal DevFest morais on app.net March ’13