KEMBAR78
Offline-Strategien für HTML5 Web Applikationen - bedcon13 | PDF
Offline Strategien für
HTML5 Web Applikationen
 Stephan Hochdörfer, bitExpert AG
Offline Strategien für HTML5 Web Applikationen

 Über mich

  Stephan Hochdörfer

  Head of IT der bitExpert AG, Mannheim

  S.Hochdoerfer@bitExpert.de

  @shochdoerfer
Offline Strategien für HTML5 Web Applikationen




        [...] we take the next step,
     announcing 2014 as the target for
              Recommendation.
    Jeff Jaffe, Chief Executive Officer, World Wide Web Consortium
Offline Strategien für HTML5 Web Applikationen

 Was bedeutet „offline“?
Offline Strategien für HTML5 Web Applikationen

 Was bedeutet „offline“?




            Applikation vs. Content
Offline Strategien für HTML5 Web Applikationen

 Was bedeutet „offline“?




  Application Cache vs. Offline Storage
Offline Strategien für HTML5 Web Applikationen

 App Cache für statische Ressourcen
 HTML Page:
 <!DOCTYPE html>
 <html lang="en">
Offline Strategien für HTML5 Web Applikationen

 App Cache für statische Ressourcen
 HTML Page:
 <!DOCTYPE html>
 <html lang="en" manifest="cache.manifest">


 cache.manifest (Content-Type: text/cache-manifest):
 CACHE MANIFEST

 js/app.js
 css/app.css
 favicon.ico
 http://someotherdomain.com/image.png
Offline Strategien für HTML5 Web Applikationen

 App Cache für statische Ressourcen
 CACHE MANIFEST
 # 2012­09­16

 NETWORK:
 data.php

 CACHE:
 /main/home
 /main/app.js
 /settings/home
 /settings/app.js
 http://myhost/logo.png
 http://myhost/check.png
 http://myhost/cross.png
Offline Strategien für HTML5 Web Applikationen

 App Cache für statische Ressourcen
 CACHE MANIFEST
 # 2012­09­16

 FALLBACK:
 / /offline.html

 NETWORK:
 *
Offline Strategien für HTML5 Web Applikationen

 App Cache Scripting
 // events fired by window.applicationCache
 window.applicationCache.onchecking = function(e) 
 {log("Checking for updates");}
 window.applicationCache.onnoupdate = function(e) 
 {log("No updates");}
 window.applicationCache.onupdateready = function(e) 
 {log("Update ready");}
 window.applicationCache.onobsolete = function(e) 
 {log("Obsolete");}
 window.applicationCache.ondownloading = function(e) 
 {log("Downloading");}
 window.applicationCache.oncached = function(e) 
 {log("Cached");}
 window.applicationCache.onerror = function(e) 
 {log("Error");}

 // Log each file
 window.applicationCache.onprogress = function(e) {
   log("Progress: downloaded file " + counter);
   counter++;
 };
Offline Strategien für HTML5 Web Applikationen

 App Cache Scripting
 // Check if a new cache is available on page load.
 window.addEventListener('load', function(e) {
   window.applicationCache.addEventListener('updateready',
   function(e) {

     if(window.applicationCache.status == 
         window.applicationCache.UPDATEREADY) {
       // Browser downloaded a new app cache.
       // Swap it in and reload the page
       window.applicationCache.swapCache();
       if (confirm('New version is available. Load it?)) {
         window.location.reload();
       }
     } else {
       // Manifest didn't change...
     }
   }, false);

 }, false);
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!




      1. Dateien werden immer(!) vom
         lokalen Cache ausgeliefert.
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!



     2. Der lokale Cache wird nur dann
     aktualisiert wenn sich die manifest
             Datei geändert hat.
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!



     3. Nicht ladbare Dateien aus der
   CACHE Sektion führen dazu dass der
            Cache invalide ist.
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!




     4. Kann die manifest Datei nicht
  geladen werden, erfolgt kein Caching!
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!




   5. Nicht gecachte Ressourcen werden
      auf einer gecachten Seite nicht
                 angezeigt.
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!




    6. Nach Aktualisierung des Caches
    muss die Seite neu geladen werden!
Offline Strategien für HTML5 Web Applikationen

 App Cache – Einige Fallstricke!




  7. Mit expires Header arbeiten um das
   Cachen des manifests zu verhinden!
Offline Strategien für HTML5 Web Applikationen

 App Cache – Was darf gecacht werden?

  Ja:                                Nein:
  
    Schriften                        
                                       CSS
  
    Startbild                        
                                       HTML
  
    Applikationsicon                 
                                       Javascript
  
    Einstiegsseite
  
    Fallbackseite
Offline Strategien für HTML5 Web Applikationen

 App Cache – Was darf gecacht werden?



           Den App Cache nur für
      „statischen Content“ verwenden!
Offline Strategien für HTML5 Web Applikationen

 Data URI Schema
Offline Strategien für HTML5 Web Applikationen

 Data URI Schema
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>The Data URI scheme</title>
   <style type="text/css">
   ul.checklist li {
     margin­left: 20px;
     background: white 
 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAA
 AFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAA
 O9TXL0Y4OHwAAAABJRU5ErkJggg==') no­repeat scroll left 
 top;
 }
   </style>
  </head>
  <body>
   <img 
 src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAA
 AFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAA
 O9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
  </body>
 </html>
Offline Strategien für HTML5 Web Applikationen

 Dynamische Daten lokal speichern...
Offline Strategien für HTML5 Web Applikationen

 Dynamische Daten lokal speichern...




                 Sourcen:
     github.com/bitExpert/html5-offline
Offline Strategien für HTML5 Web Applikationen

 Dynamische Daten lokal speichern...




     Web Storage, Web SQL Database,
           IndexedDB, File API
Offline Strategien für HTML5 Web Applikationen

 Web Storage
Offline Strategien für HTML5 Web Applikationen

 Web Storage




       Komfortable Art Daten offline zu
        speichern: Key/Value Speicher
Offline Strategien für HTML5 Web Applikationen

 Web Storage: 2 Möglichkeiten




       localStorage vs. sessionStorage
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Datensatz hinzufügen
 function add(item) {
     try {
          // for a new item set id
          if((typeof item.id === "undefined") 
              || (null == item.id) || ("" == item.id)) {
              item.id = get_lastIndex() + 1;
          }

          // store object as string
          localStorage.setItem(item.id, 
              JSON.stringify(item)
          );

         // update the index
         set_lastIndex(item.id);
     }
     catch(ex) {
         console.log(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Datensatz ändern
 function modify(item) {
     try {
          // store object as string
          localStorage.setItem(item.id, 
              JSON.stringify(item)
          );
     }
     catch(ex) {
          console.log(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Datensatz löschen
 function remove (id) {
     try {
          localStorage.removeItem(id);
     }
     catch(ex) {
          console.log(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Datensätze auslesen
 function read() {
       try {
           var lastIdx = get_lastIndex();
           for(var i = 1; i <= lastIdx; i++) {
                if(null !== localStorage.getItem(i)) {
                    // parse and render item
                    var item = JSON.parse(
                         localStorage.getItem(i)
                    );
                }
           }
       }
       catch(ex) {
           console.log(ex);
       }
 }
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Wie sessionStorage nutzen?
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Wie sessionStorage nutzen?




              Ersetze „localStorage“
              durch „sessionStorage“
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Datensatz hinzufügen
 function add(item) {
     try {
          // for a new item set id
          if((typeof item.id === "undefined") 
              || (null == item.id) || ("" == item.id)) {
              item.id = get_lastIndex() + 1;
          }

          // store object as string
          sessionStorage.setItem(item.id, 
              JSON.stringify(item)
          );

         // update the index
         set_lastIndex(item.id);
     }
     catch(ex) {
         console.log(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Alternative Zugriffsmöglichkeiten
 var value = "my value";

 // method call
 localStorage.setItem("key", value);

 // Array accessor
 localStorage[key] = value;

 // Property accessor
 localStorage.key = value;
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Vorteile




     Die meisten der aktuellen Browser
          „können“ Web Storage.
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Nachteile




          Daten werden unstrukturiert
                 gespeichert.
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Nachteile




             Nicht Transaktionsfähig!
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Nachteile




     Daten können nicht automatisch
    verfallen. Manueller Aufwand nötig.
Offline Strategien für HTML5 Web Applikationen

 Web Storage: Nachteile




     Unzureichende Informationen wie
      voll der lokale Cache wirklich ist.
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database




          Eine lokale SQL Datenbank
                auf SQLite Basis.
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Callbacks
 var onError = function(tx, ex) {
     alert("Error: " + ex.message);
 };

 var onSuccess = function(tx, results) {
     var len = results.rows.length;

      for(var i = 0; i < len; i++) {
          // render found todo item
          render(results.rows.item(i));
      }
 };
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Datenbank erzeugen
 // initalize the database connection
 var db = openDatabase('todo', '1.0', 'Todo Database', 
    5 * 1024 * 1024 );

 db.transaction(function (tx) {
     tx.executeSql(
          'CREATE TABLE IF NOT EXISTS todo '+ 
          '(id INTEGER PRIMARY KEY ASC, todo TEXT)',
          [], 
          onSuccess, 
          onError
     );
 });
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Datensatz hinzufügen
 function add(item) {
     db.transaction(function(tx) {
          tx.executeSql(
              'INSERT INTO todo (todo) VALUES (?)',
              [
                   item.todo
              ],
              onSuccess,
              onError
          );
     });
 }
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Datensatz verändern
 function modify(item) {
     db.transaction(function(tx) {
          tx.executeSql(
              'UPDATE todo SET todo = ? WHERE id = ?',
              [
                   item.todo
                   item.id
              ],
              onSuccess,
              onError
          );
     });
 }
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Datensatz löschen
 function remove(id) {
     db.transaction(function (tx) {
          tx.executeSql(
              'DELETE FROM todo WHERE id = ?',
              [
                   id
              ],
              onSuccess,
              onError
          );
     });
 }
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Datensätze auslesen
 function read() {
     db.transaction(function (tx) {
          tx.executeSql(
              'SELECT * FROM todo',
              [],
              onSuccess,
              onError
          );
     });
 }
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Vorteile




      Eine SQL Datenbank im Browser!
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Nachteile




      Eine SQL Datenbank im Browser!
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Nachteile




    SQLite kann seeeehr langsam sein!
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database: Nachteile




               Nicht länger Teil der
               HTML5 Spezifikation!
Offline Strategien für HTML5 Web Applikationen

 IndexedDB
Offline Strategien für HTML5 Web Applikationen

 IndexedDB




        Kompromiss aus Web Storage
          und Web SQL Database.
Offline Strategien für HTML5 Web Applikationen

 Web SQL Database vs. IndexedDB
 Kategorie       Web SQL                        IndexedDB
 Speicherart     Tabellen mit Spalten und       Objectstore mit Javascript Objekten und
                 Zeilen                         Keys
 Abfrage     SQL                                Cursor APIs, Key Range APIs und
 mechanismus                                    Applicationslogik
 Transaktionali Lock für Databanken,     Locks für Datenbanken
 tät            Tabellen oder Zeilen bei (VERSION_CHANGE Transaktion) und
                READ_WRITE Transaktionen Objectstores (READ_ONLY, READ_WRITE
                                         Transaktion).
 Transaktions-   Transaktionen werden explizt   Transaktionen werden explizt erzeugt.
 Commits         erzeugt. Standard: Rollback,   Standard: Committen sofern kein Fehler
                 außer es wird explizit ein     aufgetreten ist.
                 commit ausgeführt.
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Vorarbeiten
 // different browsers, different naming conventions
 var indexedDB = window.indexedDB || 
    window.webkitIndexedDB || window.mozIndexedDB || 
    window.msIndexedDB;

 var IDBTransaction = window.IDBTransaction ||
    window.webkitIDBTransaction;

 var IDBKeyRange = window.IDBKeyRange || 
    window.webkitIDBKeyRange;
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Objektspeicher erzeugen
 var db = null;
 var request = indexedDB.open("todo");
 request.onfailure = onError;
 request.onsuccess = function(e) {
     db = request.result;
     var v = "1.0";
     if(v != db.version) {
          var verRequest = db.setVersion(v);
          verRequest.onfailure = onError;
          verRequest.onsuccess = function(e) {
              var store = db.createObjectStore(
                   "todo",
                   {
                       keyPath: "id",
                       autoIncrement: true
                   }
              );
              e.target.transaction.oncomplete = 
                 function() {};
          };
     }
 };
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Datensatz hinzufügen
 function add(item) {
     try {
          var trans = db.transaction(["todo"], 
              IDBTransaction.READ_WRITE);

         var store   = trans.objectStore("todo");
         var request = store.put({
             "todo": item.todo,
         });
     }
     catch(ex) {
         onError(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Datensatz verändern
 function modify(item) {
     try {
          var trans = db.transaction(["todo"], 
              IDBTransaction.READ_WRITE);

         var store   = trans.objectStore("todo");
         var request = store.put(item);
     }
     catch(ex) {
         onError(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Datensatz löschen
 function remove(id) {
     try {
          var trans = db.transaction(["todo"],
              IDBTransaction.READ_WRITE);

         var store   = trans.objectStore("todo");
         var request = store.delete(id);
     }
     catch(ex) {
         onError(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Datensätze auslesen
 function read () {
     try {
          var trans = db.transaction(["todo"], 
              IDBTransaction.READ);

         var store = trans.objectStore("todo");
         var keyRange = IDBKeyRange.lowerBound(0);
         var cursorRequest = store.openCursor(keyRange);

         cursorRequest.onsuccess = function(e) {
             var result = e.target.result;
             if(!!result == false) {
                  return;
             }
             // @TODO: render result.value
             result.continue();
         };
     }
     catch(ex) {
         onError(ex);
     }
 }
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Vorteile




     Neuer Standard der künftig durch
      viele Browser unterstützt wird.
Offline Strategien für HTML5 Web Applikationen

 IndexedDB: Nachteile




               Nur ein Index pro
             Objektspeicher möglich.
Offline Strategien für HTML5 Web Applikationen

 File API
Offline Strategien für HTML5 Web Applikationen

 File API




      FileReader API und FileWriter API
Offline Strategien für HTML5 Web Applikationen

 File API: Vorarbeiten
 var onError = function(e) {
     var msg = '';

      switch(e.code) {
          case FileError.QUOTA_EXCEEDED_ERR:
               msg = 'QUOTA_EXCEEDED_ERR'; break;
          case FileError.NOT_FOUND_ERR:
               msg = 'NOT_FOUND_ERR'; break;
          case FileError.SECURITY_ERR:
               msg = 'SECURITY_ERR'; break;
          case FileError.INVALID_MODIFICATION_ERR:
               msg = 'INVALID_MODIFICATION_ERR'; break;
          case FileError.INVALID_STATE_ERR:
               msg = 'INVALID_STATE_ERR'; break;
          default:
               msg = 'Unknown Error'; break;
      };

      alert("Error: " + msg);
 };
Offline Strategien für HTML5 Web Applikationen

 File API: Vorarbeiten II
 // File system has been prefixed as of Google Chrome 12
 window.requestFileSystem = window.requestFileSystem ||
     window.webkitRequestFileSystem;

 window.BlobBuilder = window.BlobBuilder || 
     window.WebKitBlobBuilder;

 var size = 5 * 1024*1024; // 5MB
Offline Strategien für HTML5 Web Applikationen

 File API: Quota anfordern
 // request quota for persistent store
 window.webkitStorageInfo.requestQuota(
     PERSISTENT,
     size,
     function(grantedBytes) {
          window.requestFileSystem(
              PERSISTENT,
              grantedBytes,
              function(fs) {
                   // @TODO: access filesystem
              }
          }
     }
 }
Offline Strategien für HTML5 Web Applikationen
Offline Strategien für HTML5 Web Applikationen

 File API: Daten hinzufügen
 function add(item) {
        window.webkitStorageInfo.requestQuota(
             PERSISTENT,
             size,
             function(grantedBytes) {
                  window.requestFileSystem(
                       PERSISTENT,
                       grantedBytes,
                       function(fs){
                            writeToFile(fs, item);
                       },
                       onError
                  );
             },
             function(e) {
                  onError(e);
             }
        );
   },
Offline Strategien für HTML5 Web Applikationen

 File API: Daten hinzufügen II
 function writeToFile(fs, item) {
     fs.root.getFile(
          'todo.txt',
          {
              create: true
          },
          function(fileEntry) {
              fileEntry.createWriter(
                   function(fileWriter) {
                       var bb = new window.BlobBuilder();
                       bb.append(JSON.stringify(item)+
                           "n");

                       fileWriter.seek(fileWriter.length);
                       fileWriter.write(
                           bb.getBlob('text/plain'));
                   }, onError
              );
          }, onError
     );
 };
Offline Strategien für HTML5 Web Applikationen

 File API: Daten auslesen
 function read() {
       window.webkitStorageInfo.requestQuota(
            PERSISTENT,
            size,
            function(grantedBytes) {
                 window.requestFileSystem(
                      PERSISTENT,
                      grantedBytes,
                      function(fs){
                           readFromFile(fs);
                      },
                      onError
                 );
            },
            function(e) {
                 onError(e);
            }
       );
 }
Offline Strategien für HTML5 Web Applikationen

 File API: Daten auslesen II
 function readFromFile(fs) {
     fs.root.getFile(
          'todo.txt',
          {
              create: true
          },
          function(fileEntry) {
              fileEntry.file(function(file){
                   var reader = new FileReader();
                   reader.onloadend = function(e) {
                       if (evt.target.readyState == 
                           FileReader.DONE) {
                           // process this.result
                       }
                   };
                   reader.readAsText(file);
              });
          }, onError
     );
 }
Offline Strategien für HTML5 Web Applikationen

 Bin ich online?
Offline Strategien für HTML5 Web Applikationen

 Bin ich online?
 document.body.addEventListener("online", function () {
   // browser is online!
 }

 document.body.addEventListener("offline", function () {
   // browser is not online!
 }
Offline Strategien für HTML5 Web Applikationen

 Bin ich online? Andere Vorgehensweise...
 $.ajax({
   dataType: 'json',
   url: 'http://myappurl.com/ping',
   success: function(data){
     // ping worked
   },
   error: function() {
     // ping failed ­> Server not reachable
   }
 });
Offline Strategien für HTML5 Web Applikationen

 Browserunterstützung?
              App Cache Web Storage WebSQL IndexedDB File API Data URI
 IE             10.0          8.0    10.0      10.0      -     8.0*
 Firefox        11.0          11.0   11.0      11.0     19.0   16.0
 Chrome         18.0          18.0   18.0      18.0     18.0   18.0
 Safari          5.1          5.1     5.1       -        -     5.1
 Opera          12.1          12.1   12.1       -        -     12.1
 iOS Safari      3.2          3.2     3.2       -        -     3.2
 Android         2.1          2.1     2.1       -        -     2.1



 Quelle: http://caniuse.com
Offline Strategien für HTML5 Web Applikationen

 Speicherplatzbeschränkung?
Offline Strategien für HTML5 Web Applikationen

 Speicherplatzbeschränkung?




     Alle vorgestellten Technologien sind
           durch Quotas beschränkt.
Offline Strategien für HTML5 Web Applikationen

 Speicherplatzbeschränkung?
               App Cache Web Storage WebSQL IndexedDB          File API
  iOS 5.1        10 MB       5 MB         5 MB       5 MB
  Android 4     unlimited    5 MB          ?              ?
  Safari 5.2   unlimited     5 MB        5 MB        5 MB
  Chrome 18      5 MB        5 MB      unlimited   unlimited   unlimited
  IE 10          50 MB      10 MB       500 MB      500 MB
  Opera 11       50 MB       5 MB        5 MB        5 MB
  Firefox 11    unlimited   10 MB        50 MB      50 MB



  Minimumwerte, je nach Konfiguration ist mehr möglich.
Vielen Dank!

Offline-Strategien für HTML5 Web Applikationen - bedcon13

  • 1.
    Offline Strategien für HTML5Web Applikationen Stephan Hochdörfer, bitExpert AG
  • 2.
    Offline Strategien fürHTML5 Web Applikationen Über mich  Stephan Hochdörfer  Head of IT der bitExpert AG, Mannheim  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 11.
    Offline Strategien fürHTML5 Web Applikationen [...] we take the next step, announcing 2014 as the target for Recommendation. Jeff Jaffe, Chief Executive Officer, World Wide Web Consortium
  • 13.
    Offline Strategien fürHTML5 Web Applikationen Was bedeutet „offline“?
  • 14.
    Offline Strategien fürHTML5 Web Applikationen Was bedeutet „offline“? Applikation vs. Content
  • 15.
    Offline Strategien fürHTML5 Web Applikationen Was bedeutet „offline“? Application Cache vs. Offline Storage
  • 16.
    Offline Strategien fürHTML5 Web Applikationen App Cache für statische Ressourcen HTML Page: <!DOCTYPE html> <html lang="en">
  • 17.
    Offline Strategien fürHTML5 Web Applikationen App Cache für statische Ressourcen HTML Page: <!DOCTYPE html> <html lang="en" manifest="cache.manifest"> cache.manifest (Content-Type: text/cache-manifest): CACHE MANIFEST js/app.js css/app.css favicon.ico http://someotherdomain.com/image.png
  • 18.
    Offline Strategien fürHTML5 Web Applikationen App Cache für statische Ressourcen CACHE MANIFEST # 2012­09­16 NETWORK: data.php CACHE: /main/home /main/app.js /settings/home /settings/app.js http://myhost/logo.png http://myhost/check.png http://myhost/cross.png
  • 19.
    Offline Strategien fürHTML5 Web Applikationen App Cache für statische Ressourcen CACHE MANIFEST # 2012­09­16 FALLBACK: / /offline.html NETWORK: *
  • 20.
    Offline Strategien fürHTML5 Web Applikationen App Cache Scripting // events fired by window.applicationCache window.applicationCache.onchecking = function(e)  {log("Checking for updates");} window.applicationCache.onnoupdate = function(e)  {log("No updates");} window.applicationCache.onupdateready = function(e)  {log("Update ready");} window.applicationCache.onobsolete = function(e)  {log("Obsolete");} window.applicationCache.ondownloading = function(e)  {log("Downloading");} window.applicationCache.oncached = function(e)  {log("Cached");} window.applicationCache.onerror = function(e)  {log("Error");} // Log each file window.applicationCache.onprogress = function(e) {   log("Progress: downloaded file " + counter);   counter++; };
  • 21.
    Offline Strategien fürHTML5 Web Applikationen App Cache Scripting // Check if a new cache is available on page load. window.addEventListener('load', function(e) {   window.applicationCache.addEventListener('updateready',   function(e) {     if(window.applicationCache.status ==          window.applicationCache.UPDATEREADY) {       // Browser downloaded a new app cache.       // Swap it in and reload the page       window.applicationCache.swapCache();       if (confirm('New version is available. Load it?)) {         window.location.reload();       }     } else {       // Manifest didn't change...     }   }, false); }, false);
  • 22.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke!
  • 23.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 1. Dateien werden immer(!) vom lokalen Cache ausgeliefert.
  • 24.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 2. Der lokale Cache wird nur dann aktualisiert wenn sich die manifest Datei geändert hat.
  • 25.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 3. Nicht ladbare Dateien aus der CACHE Sektion führen dazu dass der Cache invalide ist.
  • 26.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 4. Kann die manifest Datei nicht geladen werden, erfolgt kein Caching!
  • 27.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 5. Nicht gecachte Ressourcen werden auf einer gecachten Seite nicht angezeigt.
  • 28.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 6. Nach Aktualisierung des Caches muss die Seite neu geladen werden!
  • 29.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Einige Fallstricke! 7. Mit expires Header arbeiten um das Cachen des manifests zu verhinden!
  • 30.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Was darf gecacht werden? Ja: Nein:  Schriften  CSS  Startbild  HTML  Applikationsicon  Javascript  Einstiegsseite  Fallbackseite
  • 31.
    Offline Strategien fürHTML5 Web Applikationen App Cache – Was darf gecacht werden? Den App Cache nur für „statischen Content“ verwenden!
  • 32.
    Offline Strategien fürHTML5 Web Applikationen Data URI Schema
  • 33.
    Offline Strategien fürHTML5 Web Applikationen Data URI Schema <!DOCTYPE HTML> <html>  <head>   <title>The Data URI scheme</title>   <style type="text/css">   ul.checklist li {     margin­left: 20px;     background: white  url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAA AFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAA O9TXL0Y4OHwAAAABJRU5ErkJggg==') no­repeat scroll left  top; }   </style>  </head>  <body>   <img  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAA AFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAA O9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">  </body> </html>
  • 34.
    Offline Strategien fürHTML5 Web Applikationen Dynamische Daten lokal speichern...
  • 36.
    Offline Strategien fürHTML5 Web Applikationen Dynamische Daten lokal speichern... Sourcen: github.com/bitExpert/html5-offline
  • 37.
    Offline Strategien fürHTML5 Web Applikationen Dynamische Daten lokal speichern... Web Storage, Web SQL Database, IndexedDB, File API
  • 38.
    Offline Strategien fürHTML5 Web Applikationen Web Storage
  • 39.
    Offline Strategien fürHTML5 Web Applikationen Web Storage Komfortable Art Daten offline zu speichern: Key/Value Speicher
  • 40.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: 2 Möglichkeiten localStorage vs. sessionStorage
  • 41.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Datensatz hinzufügen function add(item) { try { // for a new item set id if((typeof item.id === "undefined")               || (null == item.id) || ("" == item.id)) { item.id = get_lastIndex() + 1; } // store object as string localStorage.setItem(item.id,               JSON.stringify(item)          ); // update the index set_lastIndex(item.id); } catch(ex) { console.log(ex); } }
  • 42.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Datensatz ändern function modify(item) { try { // store object as string localStorage.setItem(item.id,               JSON.stringify(item)          ); } catch(ex) { console.log(ex); } }
  • 43.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Datensatz löschen function remove (id) { try { localStorage.removeItem(id); } catch(ex) { console.log(ex); } }
  • 44.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Datensätze auslesen function read() {       try {       var lastIdx = get_lastIndex();       for(var i = 1; i <= lastIdx; i++) {       if(null !== localStorage.getItem(i)) {       // parse and render item       var item = JSON.parse(                         localStorage.getItem(i)                    );       }       }       }       catch(ex) {       console.log(ex);       } }
  • 45.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Wie sessionStorage nutzen?
  • 46.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Wie sessionStorage nutzen? Ersetze „localStorage“ durch „sessionStorage“
  • 47.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Datensatz hinzufügen function add(item) { try { // for a new item set id if((typeof item.id === "undefined")               || (null == item.id) || ("" == item.id)) { item.id = get_lastIndex() + 1; } // store object as string sessionStorage.setItem(item.id,               JSON.stringify(item)          ); // update the index set_lastIndex(item.id); } catch(ex) { console.log(ex); } }
  • 48.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Alternative Zugriffsmöglichkeiten var value = "my value"; // method call localStorage.setItem("key", value); // Array accessor localStorage[key] = value; // Property accessor localStorage.key = value;
  • 50.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Vorteile Die meisten der aktuellen Browser „können“ Web Storage.
  • 51.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Nachteile Daten werden unstrukturiert gespeichert.
  • 52.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Nachteile Nicht Transaktionsfähig!
  • 53.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Nachteile Daten können nicht automatisch verfallen. Manueller Aufwand nötig.
  • 54.
    Offline Strategien fürHTML5 Web Applikationen Web Storage: Nachteile Unzureichende Informationen wie voll der lokale Cache wirklich ist.
  • 55.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database
  • 56.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database Eine lokale SQL Datenbank auf SQLite Basis.
  • 57.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Callbacks var onError = function(tx, ex) { alert("Error: " + ex.message); }; var onSuccess = function(tx, results) { var len = results.rows.length; for(var i = 0; i < len; i++) { // render found todo item render(results.rows.item(i)); } };
  • 58.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Datenbank erzeugen // initalize the database connection var db = openDatabase('todo', '1.0', 'Todo Database',     5 * 1024 * 1024 ); db.transaction(function (tx) { tx.executeSql( 'CREATE TABLE IF NOT EXISTS todo '+           '(id INTEGER PRIMARY KEY ASC, todo TEXT)', [],           onSuccess,           onError ); });
  • 59.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Datensatz hinzufügen function add(item) { db.transaction(function(tx) { tx.executeSql( 'INSERT INTO todo (todo) VALUES (?)', [ item.todo ], onSuccess, onError ); }); }
  • 60.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Datensatz verändern function modify(item) { db.transaction(function(tx) { tx.executeSql( 'UPDATE todo SET todo = ? WHERE id = ?', [ item.todo item.id ], onSuccess, onError ); }); }
  • 61.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Datensatz löschen function remove(id) { db.transaction(function (tx) { tx.executeSql( 'DELETE FROM todo WHERE id = ?', [ id ], onSuccess, onError ); }); }
  • 62.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Datensätze auslesen function read() { db.transaction(function (tx) { tx.executeSql( 'SELECT * FROM todo', [], onSuccess, onError ); }); }
  • 63.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Vorteile Eine SQL Datenbank im Browser!
  • 64.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Nachteile Eine SQL Datenbank im Browser!
  • 65.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Nachteile SQLite kann seeeehr langsam sein!
  • 66.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database: Nachteile Nicht länger Teil der HTML5 Spezifikation!
  • 67.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB
  • 68.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB Kompromiss aus Web Storage und Web SQL Database.
  • 69.
    Offline Strategien fürHTML5 Web Applikationen Web SQL Database vs. IndexedDB Kategorie Web SQL IndexedDB Speicherart Tabellen mit Spalten und Objectstore mit Javascript Objekten und Zeilen Keys Abfrage SQL Cursor APIs, Key Range APIs und mechanismus Applicationslogik Transaktionali Lock für Databanken, Locks für Datenbanken tät Tabellen oder Zeilen bei (VERSION_CHANGE Transaktion) und READ_WRITE Transaktionen Objectstores (READ_ONLY, READ_WRITE Transaktion). Transaktions- Transaktionen werden explizt Transaktionen werden explizt erzeugt. Commits erzeugt. Standard: Rollback, Standard: Committen sofern kein Fehler außer es wird explizit ein aufgetreten ist. commit ausgeführt.
  • 70.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Vorarbeiten // different browsers, different naming conventions var indexedDB = window.indexedDB ||     window.webkitIndexedDB || window.mozIndexedDB ||     window.msIndexedDB; var IDBTransaction = window.IDBTransaction ||    window.webkitIDBTransaction; var IDBKeyRange = window.IDBKeyRange ||     window.webkitIDBKeyRange;
  • 71.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Objektspeicher erzeugen var db = null; var request = indexedDB.open("todo"); request.onfailure = onError; request.onsuccess = function(e) { db = request.result; var v = "1.0"; if(v != db.version) { var verRequest = db.setVersion(v); verRequest.onfailure = onError; verRequest.onsuccess = function(e) { var store = db.createObjectStore( "todo", { keyPath: "id", autoIncrement: true } ); e.target.transaction.oncomplete =                  function() {}; }; } };
  • 72.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Datensatz hinzufügen function add(item) { try { var trans = db.transaction(["todo"],               IDBTransaction.READ_WRITE); var store   = trans.objectStore("todo"); var request = store.put({ "todo": item.todo, }); } catch(ex) { onError(ex); } }
  • 73.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Datensatz verändern function modify(item) { try { var trans = db.transaction(["todo"],               IDBTransaction.READ_WRITE); var store   = trans.objectStore("todo"); var request = store.put(item); } catch(ex) { onError(ex); } }
  • 74.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Datensatz löschen function remove(id) { try { var trans = db.transaction(["todo"],              IDBTransaction.READ_WRITE); var store   = trans.objectStore("todo"); var request = store.delete(id); } catch(ex) { onError(ex); } }
  • 75.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Datensätze auslesen function read () { try { var trans = db.transaction(["todo"],               IDBTransaction.READ); var store = trans.objectStore("todo"); var keyRange = IDBKeyRange.lowerBound(0); var cursorRequest = store.openCursor(keyRange); cursorRequest.onsuccess = function(e) { var result = e.target.result; if(!!result == false) { return; } // @TODO: render result.value result.continue(); }; } catch(ex) { onError(ex); } }
  • 76.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Vorteile Neuer Standard der künftig durch viele Browser unterstützt wird.
  • 77.
    Offline Strategien fürHTML5 Web Applikationen IndexedDB: Nachteile Nur ein Index pro Objektspeicher möglich.
  • 78.
    Offline Strategien fürHTML5 Web Applikationen File API
  • 79.
    Offline Strategien fürHTML5 Web Applikationen File API FileReader API und FileWriter API
  • 80.
    Offline Strategien fürHTML5 Web Applikationen File API: Vorarbeiten var onError = function(e) { var msg = ''; switch(e.code) { case FileError.QUOTA_EXCEEDED_ERR: msg = 'QUOTA_EXCEEDED_ERR'; break; case FileError.NOT_FOUND_ERR: msg = 'NOT_FOUND_ERR'; break; case FileError.SECURITY_ERR: msg = 'SECURITY_ERR'; break; case FileError.INVALID_MODIFICATION_ERR: msg = 'INVALID_MODIFICATION_ERR'; break; case FileError.INVALID_STATE_ERR: msg = 'INVALID_STATE_ERR'; break; default: msg = 'Unknown Error'; break; }; alert("Error: " + msg); };
  • 81.
    Offline Strategien fürHTML5 Web Applikationen File API: Vorarbeiten II // File system has been prefixed as of Google Chrome 12 window.requestFileSystem = window.requestFileSystem ||     window.webkitRequestFileSystem; window.BlobBuilder = window.BlobBuilder ||      window.WebKitBlobBuilder; var size = 5 * 1024*1024; // 5MB
  • 82.
    Offline Strategien fürHTML5 Web Applikationen File API: Quota anfordern // request quota for persistent store window.webkitStorageInfo.requestQuota( PERSISTENT, size, function(grantedBytes) { window.requestFileSystem( PERSISTENT, grantedBytes, function(fs) { // @TODO: access filesystem } } } }
  • 83.
    Offline Strategien fürHTML5 Web Applikationen
  • 84.
    Offline Strategien fürHTML5 Web Applikationen File API: Daten hinzufügen function add(item) {   window.webkitStorageInfo.requestQuota(   PERSISTENT,   size,   function(grantedBytes) {   window.requestFileSystem(   PERSISTENT,   grantedBytes,   function(fs){   writeToFile(fs, item);   },   onError   );   },   function(e) {   onError(e);   }   );   },
  • 85.
    Offline Strategien fürHTML5 Web Applikationen File API: Daten hinzufügen II function writeToFile(fs, item) { fs.root.getFile( 'todo.txt', { create: true }, function(fileEntry) { fileEntry.createWriter( function(fileWriter) { var bb = new window.BlobBuilder(); bb.append(JSON.stringify(item)+                           "n"); fileWriter.seek(fileWriter.length); fileWriter.write(                           bb.getBlob('text/plain')); }, onError ); }, onError ); };
  • 86.
    Offline Strategien fürHTML5 Web Applikationen File API: Daten auslesen function read() {   window.webkitStorageInfo.requestQuota(   PERSISTENT,   size,   function(grantedBytes) {   window.requestFileSystem(   PERSISTENT,   grantedBytes,   function(fs){   readFromFile(fs);   },   onError   );   },   function(e) {   onError(e);   }   ); }
  • 87.
    Offline Strategien fürHTML5 Web Applikationen File API: Daten auslesen II function readFromFile(fs) { fs.root.getFile( 'todo.txt', { create: true }, function(fileEntry) { fileEntry.file(function(file){ var reader = new FileReader(); reader.onloadend = function(e) { if (evt.target.readyState ==      FileReader.DONE) {     // process this.result } }; reader.readAsText(file); }); }, onError ); }
  • 88.
    Offline Strategien fürHTML5 Web Applikationen Bin ich online?
  • 89.
    Offline Strategien fürHTML5 Web Applikationen Bin ich online? document.body.addEventListener("online", function () {   // browser is online! } document.body.addEventListener("offline", function () {   // browser is not online! }
  • 90.
    Offline Strategien fürHTML5 Web Applikationen Bin ich online? Andere Vorgehensweise... $.ajax({   dataType: 'json',   url: 'http://myappurl.com/ping',   success: function(data){     // ping worked   },   error: function() {     // ping failed ­> Server not reachable   } });
  • 91.
    Offline Strategien fürHTML5 Web Applikationen Browserunterstützung? App Cache Web Storage WebSQL IndexedDB File API Data URI IE 10.0 8.0 10.0 10.0 - 8.0* Firefox 11.0 11.0 11.0 11.0 19.0 16.0 Chrome 18.0 18.0 18.0 18.0 18.0 18.0 Safari 5.1 5.1 5.1 - - 5.1 Opera 12.1 12.1 12.1 - - 12.1 iOS Safari 3.2 3.2 3.2 - - 3.2 Android 2.1 2.1 2.1 - - 2.1 Quelle: http://caniuse.com
  • 92.
    Offline Strategien fürHTML5 Web Applikationen Speicherplatzbeschränkung?
  • 93.
    Offline Strategien fürHTML5 Web Applikationen Speicherplatzbeschränkung? Alle vorgestellten Technologien sind durch Quotas beschränkt.
  • 94.
    Offline Strategien fürHTML5 Web Applikationen Speicherplatzbeschränkung? App Cache Web Storage WebSQL IndexedDB File API iOS 5.1 10 MB 5 MB 5 MB 5 MB Android 4 unlimited 5 MB ? ? Safari 5.2 unlimited 5 MB 5 MB 5 MB Chrome 18 5 MB 5 MB unlimited unlimited unlimited IE 10 50 MB 10 MB 500 MB 500 MB Opera 11 50 MB 5 MB 5 MB 5 MB Firefox 11 unlimited 10 MB 50 MB 50 MB Minimumwerte, je nach Konfiguration ist mehr möglich.
  • 95.