indexeddb - querying and performance
Post on 18-Oct-2014
11.316 views
DESCRIPTION
Talk at HTMl5DevConf on April 1, 2013 about IndexedDB, Plugins for IndexedDB and performance analysis of IndexedDB.TRANSCRIPT
Prepare yourselves
The Mobile has arrived
Go where no website has gone before
Scotty, beam me up
I have good internet bandwidth
Work when you are disconnected too
Darth Vader Says
What if I told you
that adding Offline support is easy ?
A simple website
DATA inSERVER
DATA inBROWSER
SHOW ME
http://nparashuram.com/conference
var Session = Backbone.Model.extend({});var SessionList = Backbone.Collection.extend({});
var singleSession = new Session();singleSession.get(101);view.update(singleSession);
var allSessions = new SessionList();allSessions.fetch();view.render(allSessions);
Simple Read OperationAjaxHandler = { getSession: function (id) { // code goes here }, getAllSessions: function () { // code goes here }}
Backbone.sync = function (method, model, options, error) { switch (method) { case "read": // Methods for reading from database break; case "create": // Create a record here break; case "update": // Update Records break; case "delete": // Delete record }RemoteDatabase.replicate();});
case "read":// Pseudo Codeif (model.id) {// for a single Model db.get(model.id, function (err, res) { if (err) { error(err); return; } options.success(res); } );} else { // For all rows in the DB db.getAll ( function (err, resp) { if (err) { error(err); return; } options.success(resp); } );}
I totally understand you
With all that pseudo code
case "read": // Real IndexedDB Codeif (model.id) {// for a single Model var openReq = window.indexedDB.open("DatabaseName"); openReq.onsuccess = function () { var db = openReq.result; var transaction = db.transaction(["Model1”], "readonly"); var objectStore = transaction.objectStore("Model1"); var readReq = objectStore.get(model.id); readReq.onsuccess = function () { option.success(readReq.result); }; }; openReq.onerror = function (e) { options.error(e); };}
What did you just do ?
IndexedDB Refresher
http://yourwebpage.com search
Database
Cursor on Object Store
Object Store
key : value
key : value
key : value
Index
Cursor on Index
Database
Cursor on Object Store
Object Store
key : value
key : value
key : value
Index
Cursor on Index
Transaction
case "read":
if (model.id) { var openReq = window.indexedDB.open("DatabaseName"); openReq.onsuccess = function () { var db = openReq.result; var transaction = db.transaction(["Model1”], "readonly"); var objectStore = transaction.objectStore("Model1"); var readReq = objectStore.get(model.id); readReq.onsuccess = function () { option.success(readReq.result); }; }; openReq.onerror = function (e) { options.error(e); };}
You wrote so much code
Just to read a single record ?
case "read": // Jquery-IndexedDB Pluginif (model.id) { var openReq = window.indexedDB.open("DatabaseName"); openReq.onsuccess = function () { var db = openReq.result; var transaction = db.transaction(["Model1”], "readonly"); var objectStore = transaction.objectStore("Model1"); var readReq = objectStore.get(model.id); readReq.onsuccess = function () { option.success(readReq.result); };
readReq.onerror = function (e) { options.error(e); }; }; openReq.onerror = function (e) { options.error(e); };}
$.indexedDB("DatabaseName")
.objectStore("Model1") .get(model.id) .done(function(data) { }) .fail(function (error) {
});
case "read": // Jquery-IndexedDB Plugin$.indexedDB("DatabaseName") .objectStore("Model1") .get(model.id) .done(function (data) { option.success(data); }).fail(function (error) { option.error(error); });
$.indexedDB("DatabaseName") .objectStore("Model1") .each(function (record) { display(record); }).done(function () { // Finished with all records }).fail(function () { // Error });
• Less Verbose• Chainable API• Use Promises• Smart Defaults• Almost transparent
Project : gitbhub/axemclion/jquery-indexeddb
case "read":// Pouch DB Codeif (model.id) {// for a single Model db.get(model.id, {}, function (err, res) { if (err) { error(err); return; } options.success(res); } );} else { // For all rows in the DB db.allDocs ({}, function (err, resp) { if (err) { error(err); return; } options.success(resp); } );}
Pouch DB API
Project : http://pouchdb.com
Pouch.replicate("idb://data","http://me.couchdb.com/data");
Sure, but can you query data ?
$.indexedDB("DatabaseName") .objectStore("Model1") .where('price < 100') .sortBy('price') .desc()
Querying IndexedDB
objectStore.index('price').openCursor( IDBKeyRange.lowerBound(100, false), "prev");
$.indexedDB("DatabaseName") .objectStore("Model1") .where('price < 100 and >= 200') .sortBy('price') .desc()
Querying IndexedDB
objectStore.index('price').openCursor( IDBKeyRange.bound(100, 200, false, true), "prev");
$.indexedDB("DatabaseName") .objectStore("Model1") .where('price < 100 and >= 200') .sortBy('name') .desc() .done(function(results){ // do something with results // results.length == ??? })
Querying IndexedDB
var results =
objectStore.index('price').openCursor( IDBKeyRange.bound(100, 200, false, true), "prev");
$.indexedDB("DatabaseName") .objectStore("Model1") .where('price < 100 and >= 200') .where('ratings > 4') .sortBy('name') .desc() .each(function(result){ // process each result })
Querying IndexedDB
cursorReq = objectStore.index('name').openCursor();cursorReq.onsuccess = function () { if (cursorReq.result) {
val = cursorReq.result.value; if (val.price < 100 && val.price > 200 ) callback(val); cursorReq.result.continue(); }}
&& val.ratings > 4)
.done(function(results){ // do something with results // results.length == ??? })
$.indexedDB("DatabaseName") .objectStore("Model1") .where('price < 100 and >= 200') .where(‘Model2.empId < 5') .sortBy('name') .sortBy('price') .each(function(result){ // process each result });
Querying IndexedDB
$.indexedDB("DatabaseName") .objectStore("Model1") .where('price < 100 and >= 200') .where(‘Model2.empId < 5 ') .sortBy('name') .sortBy('price') .each(function(result){ // process each result });
Querying IndexedDB
Fall back on Web Workers to do the job
• Sorting on multiple columns• Where clauses across object stores• Sorting and clauses across object stores
Project : //linq2indexeddb.codeplex.com/
ONE DOES NOT SIMPLY START USING INDEXEDDB
WITHOUT LOOKING AT PERFORMANCE
Comparing IndexedDB and WebSQL ?
Performance Analysis
• Common cases when writing an application• Are string keys slower than integer keys• Should I combine read and write transactions ?
• Started with JSPerf, Problems with Async Setup• Using Benchmarkjs
Thanks to @slace for helping with code reviews
http://nparashuram.com/IndexedDB/perf
May the force be with you
http://nparashuram.com
@nparashuram
Resources
@OpenAtMicrosoft(@obloch)
http://nparashuram.com/IndexedDBhttp://www.html5labs.com/