Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Client-Side Storage: Past, Present and Future

Client-Side Storage: Past, Present and Future

A brief history of client-side storage followed by a more in-depth review of Web Storage, Web SQL Database and Indexed Database before concluding with a look towards the Filesystem API

Philip Battle

July 22, 2014
Tweet

Other Decks in Programming

Transcript

  1. Client-Side Storage: Past, Present and Future A brief history of

    client-side storage followed by a more in-depth review of Web Storage, Web SQL Database and Indexed Database before concluding with a look towards the Filesystem API Philip Battle https://mailtrack.io/
  2. Table of contents • What is client-side storage? • Brief

    History • Cookies • Web SQL Database • Web Storage • Indexed Database • Libraries • Filesystem API
  3. What is client-side storage? • “Client-side storage serves to give

    the web browser a memory.” Javascript: The Definitive Guide, O’Reilly • Allows for the retention of state between the client and server • Data is stored on the user's hard drive • Stores basic user preferences or even a web apps complete state (think offline Gmail)
  4. Brief History • Ubiquitous cookies invented by Lou Montulli around

    1994 • Flash Cookies (LSO) • window.name • IE userData persistance • Google Gears (Web browser extension)
  5. Cookies (the past?) Advantages! • Supported in all modern browsers

    • Reliable • Session or persistent ! ! Disadvantages! • Store only very small amounts of string data (4k) • Travel from browser to server with every HTTP request • Vulnerable to attack • Awkward JavaScript API • Synchronous
  6. WebSQL DB (the past!) Web SQL is a W3C module

    for storing data in a database within the browser. The spec defines an API on top of the standard SQLite 3.1.19 database, which uses a single file to store data.
  7. Since November 18, 2010, the W3C announced that Web SQL

    database is a deprecated Mozilla article: Beyond HTML5: Database APIs and the Road to IndexedDB
  8. Example code… var db = openDatabase('documents', '1.0', ‘Offline storage', 5*1024*1024

    /* modal */ /* creationCallback */ ); ! db.transaction(function(tx) { tx.executeSql("CREATE TABLE IF NOT EXISTS tasks (id REAL UNIQUE, text TEXT, blob BLOB)”, [] /* SQLStatementCallback */ /* errorCallback*/); });
  9. WebSQL DB Advantages! • Uses SQL syntax like many server

    side applications • Webkit support • The user interface will ask permission scale up the database size: 5, 10, 50, 100 and 500MB etc. • Good search performance • Asynchronous Disadvantages! • Abandoned by standards authority • Vendors likely to drop support • SQL doesn't seem appropriate for client-side development • Rigid lacking agility since schema must be defined upfront
  10. Web Storage (the present) Web Storage aka DOM Storage supports

    persistent data storage, similar to cookies but with a greatly enhanced capacity.
  11. Example code… // Is localStorage available? if (typeof window.localStorage !==

    'undefined') { ! // Store localStorage.setItem('greeting', 'Hello World!'); ! // Retrieve console.log(localStorage.getItem('greeting‘)); ! // Delete localStorage.removeItem('greeting'); }
  12. Further API calls // Clear localstorage.clear(); ! // Event listener

    window.addEventListener('storage', function(event) { var key = event.key; var oldValue = event.oldValue; var newValue = event.newValue; var url = event.url; // Address of the page var storageArea = event.storageArea; ! // Handle event });
  13. Web Storage Advantages! • Supported in all modern browsers •

    Simple API • Session or persistent • Event model • Pollyfills Disadvantages! • Store only ~5Mb • Unstructured data with no transactions, indexing or searching facilties • Synchronous • Poor performance for large/ complex data (lack of indexing)
  14. IndexedDB (near future) IndexedDB is an API for client-side storage

    of significant amounts of structured data and for high performance searches on this data using indexes.
  15. Key concepts • IndexedDB databases store key-value pairs • IndexedDB

    is built on a transactional database model • The IndexedDB API is mostly asynchronous • IndexedDB is object-oriented • IndexedDB uses requests almost everywhere
  16. Example code… // Vendor prefixes window.indexedDB = window.indexedDB || window.mozIndexedDB

    || window.webkitIndexedDB || window.msIndexedDB; ! var db; var request = window.indexedDB.open("customers", 1); // returns IDBOpenDBRequest ! request.onerror = function(event) { console.log("error: ", event.target.errorCode); }; ! request.onsuccess = function(event) { db = request.result; }; !
  17. Version control request.onupgradeneeded = function(event) { var db = event.target.result;

    ! // Create an objectStore var objectStore = db.createObjectStore("customers",{ keyPath: "id" // The objects must have a unique property with the same name as the keyPath /* autoIncrement: true */ /* out-of-line key */ }); ! …
  18. Create indices … ! // Create an index to search

    customers by name. We may have duplicates so we can't use a unique index. objectStore.createIndex("name", "name", {unique: false}); ! // Create an index to search customers by email. We want to ensure that no two customers have the same email, so use a unique index. objectStore.createIndex("email", "email", {unique: true}); ! …
  19. Adding data inside transactions … ! // “readwrite” transaction. “read-only”

    by default var customerObjectStore = db.transaction(["customers"], "readwrite").objectStore("customers"); ! customerObjectStore.add({ id: "658-44-4444", name: "Philip", age: 35, email: “[email protected]" }); ! customerObjectStore.add({ id: "658-55-5555", name: "Jose", age: 36, email: "[email protected]" }); ! customerObjectStore.add({ id: "658-66-6666", name: "Anne", age: 37, email: "[email protected]" }); };
  20. Update var objectStore = db.transaction(["customers"], "readwrite").objectStore("customers"); ! var request =

    objectStore.get("658-44-4444"); ! request.onsuccess = function(event) { // Get the old value that we want to update var data = request.result; ! // Update the value(s) in the object that you want to change data.age = 42; ! // Put this updated object back into the database. objectStore.put(data); };
  21. Using an index var index = objectStore.index("name"); ! index.get("Philip").onsuccess =

    function(event) { console.log(“Philip's id is " + event.target.result.id); };
  22. Using a cursor objectStore.openCursor().onsuccess = function(event) { var cursor =

    event.target.result; ! if (cursor) { console.log("Name for id " + cursor.key + " is " + cursor.value.name); customers.push(cursor.value); cursor.continue(); // Ascending order } else { console.log("No more entries!"); } };
  23. Specifying the range and direction of cursors // Match anything

    between "Philip" and "Anne", but not including "Anne" var boundKeyRange = IDBKeyRange.bound("Philip", "Anne", false, true); ! index.openCursor(boundKeyRange, "prev").onsuccess = function(event) { var cursor = event.target.result; ! if (cursor) { // Do something with the matches. cursor.continue(); } };
  24. IndexedDB Advantages! • Robust client-side data storage and access •

    good browsers support • No limit on the database's size. The user interface will just ask permission for storing blobs bigger than 50 MB • Good performance (indexes) • Non blocking API Disadvantages! • The API is very new, complex, and subject to revision • Little support in older and mobile browsers • Difficult and largely impractical to create a IndexedDB polyfill • like any NoSQL store, data is unstructured which can lead to integrity issues
  25. Filesystem API (the future) The previous formats are all suitable

    for text and structured data, but when it comes to large files and binary content, we need something else.
  26. Key concepts • The File System API is a virtual

    representation of a file system • The File System API can use different storage types • Browsers impose storage quotas • The File System API has asynchronous and synchronous versions • The File System API interacts with other APIs
  27. Example code… var fs = requestFileSystemSync(TEMPORARY, 1024*1024 /* successCallback */

    /* error Callback */); ! fs.root.getFile('log.txt', {create: true, exclusive: true}, function(fileEntry) { ! // fileEntry.isFile === true // fileEntry.name == 'log.txt' // fileEntry.fullPath == '/log.txt' ! }, errorHandler);
  28. Filesystem API Advantages! • Can store large content and binary

    files, so it's suitable for images, audio, video etc • Good performance, having an asynchronous API ! Disadvantages! • Very early standard. Only available in Chrome and Opera • No transaction support • No built-in search/indexing support