插入时IndexedDB变慢

我在第三代iPad上安装了iOS 8,并在Safari中尝试了IndexedDB。 我的示例代码只是将1000个对象添加到对象存储。

它的工作原理与其他具有相似或较弱硬件的设备相比非常慢。

看到这个片段的实现细节(IndexedDB似乎被禁用在stackoverflow,所以这个例子不工作的框 – 用这个小提琴代替 ):

添加了片段jsbin,因为jsfiddle在iOS设备上引发SecurityException并使用Deni Spasovskis更新http://jsbin.com/jorohe/1/更新。 问题仍然存在。

原始码:

var openRequest = window.indexedDB.open("testdb"); openRequest.onsuccess = function (event) { document.getElementById("output").innerHTML += "open success<br/>"; var db = event.target.result; var trans = db.transaction(["testStore"], (typeof IDBTransaction.READ_ONLY !== "undefined") ? IDBTransaction.READ_WRITE : "readwrite" ); var store = trans.objectStore("testStore"); var reqClear = store.clear(); reqClear.onsuccess = function () { var objectsToAdd = 1000; var addedObjects = 0; var startTime = window.performance.now(); for (var i=0; i<objectsToAdd; i++) { (function (pos) { var req = store.add({testID: pos, a: "foo", b: "bar"}); req.onsuccess = function () { addedObjects++; if (addedObjects >= objectsToAdd) { document.getElementById("output").innerHTML += "done adding<br />"; document.getElementById("output").innerHTML += "Took: "+(window.performance.now() - startTime)+"ms<br />"; } } req.onerror = function () { document.getElementById("output").innerHTML += "error adding element:" + req.error + " <br/>"; } })(i); } } reqClear.onerror = function () { document.getElementById("output").innerHTML += "error clearing store: "+reqClear.error+"<br/>"; } }; openRequest.onupgradeneeded = function (event) { var db = event.target.result; var objectStore = db.createObjectStore("testStore", { keyPath: "testID" }); document.getElementById("output").innerHTML += "created store<br/>"; }; openRequest.onerror = openRequest.onabort = function () { document.getElementById("output").innerHTML += "error opening db<br/>"; } 
 <div id="output"> </div> 

iPad花了大约6秒,而HTC Windows Phone 8s(弱硬件)上的Internet Explorer只花费了1.5秒,三星Galaxy S III上的Chrome(可能与iPad相媲美)在300毫秒内完成了插入操作。

虽然我明白这项技术是iOS上的新function,但我并不期望这样的性能下降。

代码有什么问题吗?还有其他方法可以在iOS设备上使用IndexedDB实现良好的性能吗?

为了在批量插入时获得最佳性能,您不应该在每个添加语句上监听事件,而应该附加事务oncompleteonerror事件。

我已经改变了一下你的代码,并在我的手机(nexus 4)上得到了15%的性能提升(〜340ms下降了约290ms)。 但是与个人电脑相比这还是比较慢的。

代码片段不起作用,所以这里是链接到jsFiddle: http : //jsfiddle.net/a5p6mL6m/2/

 var openRequest = window.indexedDB.open("testdb"); openRequest.onsuccess = function (event) { document.getElementById("output").innerHTML += "open success<br/>"; var db = event.target.result; var trans = db.transaction(["testStore"], (typeof IDBTransaction.READ_ONLY !== "undefined") ? IDBTransaction.READ_WRITE : "readwrite" ); var store = trans.objectStore("testStore"); var startTime; trans.oncomplete = function () { document.getElementById("output").innerHTML += "finished adding<br />"; document.getElementById("output").innerHTML += "End time: "+(window.performance.now() - startTime)+"<br />"; } var reqClear = store.clear(); reqClear.onsuccess = function () { startTime = window.performance.now(); var objectsToAdd = 1000; var addedObjects = 0; for (var i=0; i<objectsToAdd; i++) { store.add({testID: i, a: "foo", b: "bar"}); } } reqClear.onerror = function () { document.getElementById("output").innerHTML += "error clearing store: "+reqClear.error+"<br/>"; } }; openRequest.onupgradeneeded = function (event) { var db = event.target.result; var objectStore = db.createObjectStore("testStore", { keyPath: "testID" }); document.getElementById("output").innerHTML += "created store<br/>"; }; openRequest.onerror = openRequest.onabort = function () { document.getElementById("output").innerHTML += "error opening db<br/>"; } 
 <div id="output"> </div>