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

Taking Web Apps Offline

on

  • 1,053 views

 

Statistics

Views

Total Views
1,053
Views on SlideShare
624
Embed Views
429

Actions

Likes
0
Downloads
5
Comments
0

4 Embeds 429

http://morais.it 426
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 Taking Web Apps Offline Presentation Transcript

    • Takingweb appsoffline pedro@morais.it @pedromoraisGDG Portugal DevFest morais on app.net March ’13
    • 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’: ‘Lisbon’});
    • 92.25% http://caniuse.com/indexeddb
    • localStorage limitations Storage Limits Spec - 5 Mb Firefox - can adjusted Chrome - 2600k chars (5 mb in UTF-16) IE - 5000k chars
    • 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 & microsoft: “not gonna happen”
    • 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.onsuccess = function(event) { ...};
    • indexed db Opening a databasevar request = indexedDB.open("MyTestDatabase");request.onerror = ...var db;request.onsuccess = function(event) { db = request.result;};
    • creating the schemavar request = indexedDB.open("MyTestDatabase", 5);...request.onupgradeneeded = function(event) { var db = event.target.result; ...};
    • 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 });};
    • 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
    • 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};
    • 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};
    • deleting data...var objectStore = transaction.objectStore("customers");var request = objectStore.delete(‘44124’);request.onsuccess = function(event) { // deleted};
    • 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);};
    • 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!");  }};
    • 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
    • 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();  }};
    • 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
    • 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.htmlNETWORK:*
    • 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
    • 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!
    • 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: * + far future expires
    • cache manifest versions CACHE MANIFEST b3c4de/css/styles.css adf341/js/scripts.js ef3451/images/logo.png NETWORK: * + far future expires
    • conclusion
    • Available today localStorage Indexed DB (+ polyfill) AppCacheTake your web apps offline
    • Thanks! pedro@morais.it @pedromoraisGDG Portugal DevFest morais on app.net March ’13