我在第三代iPad上安装了iOS 8,并在Safari中尝试了IndexedDB。我的示例代码只是将1000个对象添加到对象库中。
然而,与具有相似或较弱硬件的其他设备相比,它非常慢。
请参阅此片段了解实现详细信息(在stackoverflow上似乎禁用了IndexedDB,因此该示例不能立即使用 - 使用this fiddle而不是):
将片段添加到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上是新的,但我并没有想到会有如此苛刻的性能下降。
代码有什么问题,还是有其他方法可以在iOS设备上使用IndexedDB获得不错的性能?
答案 0 :(得分:1)
为了在批量插入时获得最佳性能,您不应该在每个add语句上侦听事件,而应该附加到事务oncomplete
和onerror
事件。
我已经改变了你的代码并且在我的手机上获得了15%的性能提升(从~340ms下降约290ms)(nexus 4)。但与PC相比,这仍然很慢。
代码段不起作用,因此这里是指向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>