插入时IndexedDB会变慢

时间:2014-09-18 13:36:46

标签: ios mobile-safari ios8 indexeddb

我在第三代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获得不错的性能?

1 个答案:

答案 0 :(得分:1)

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

我已经改变了你的代码并且在我的手机上获得了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>