IndexedDB slow when inserting

坚强是说给别人听的谎言 提交于 2019-12-23 15:29:56

问题


I installed iOS 8 on a third generation iPad and tried IndexedDB in Safari. My sample code just adds 1000 objects to an object store.

It works however it is very slow compared to other devices with similar or weaker hardware.

See this snippet for implementation details (IndexedDB seems to be disabled on stackoverflow so the example does not work out of the box - use this fiddle instead):

Added the snippet to jsbin because jsfiddle raises a SecurityException on iOS device and updated with Deni Spasovskis answer http://jsbin.com/jorohe/1/. The problem still persists.

Original code:

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>

The iPad took around 6 seconds while Internet Explorer on a HTC Windows Phone 8s (weaker hardware) only took 1,5 seconds and Chrome on a Samsung Galaxy S III (which might be comparable to the iPad) finished the insert in 300 milliseconds.

While I understand that this technology is new on iOS I was not expecting such a harsh performance decrease.

Is there anything wrong with the code or is there any other way to achieve decent performance with IndexedDB on iOS devices?


回答1:


For optimal performance when batch inserting you shouldn't listen for events on every add statement, instead you should attach to the transaction oncomplete and onerror events.

I've changed your code a bit and got 15% performance increase (~290ms down from ~340ms) on my phone (nexus 4). But this is still slow when compared to the PC.

The code snippet doesn't work so here is link to the 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>


来源:https://stackoverflow.com/questions/25914265/indexeddb-slow-when-inserting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!