插入时IndexedDB会变慢 [英] IndexedDB slow when inserting

查看:154
本文介绍了插入时IndexedDB会变慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



但是与其他具有相似或较弱硬件的设备相比,它的速度非常慢。



有关实现的详细信息,请参阅此代码段(在stackoverflow上似乎禁用了IndexedDB,因此该示例不能立即使用 - 使用这个小提琴而不是):



添加了片段到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 added< br />; document.getElementById(output)。innerHTML + =采取:+(window.performance.now() -  startTime)+ms< br />;}} req.onerror = function(){document.getElementById(output)。innerHTML + =添加错误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打开db< br />;}  

 < div id =output>< / div>  



iPad占用大约6秒,而HTC Windows Phone 8s(较弱的硬件)上的Internet Explorer只用了1.5秒,而三星Galaxy S III上的Chrome(可能与iPad相当)在300毫秒内完成了插入。 / p>

虽然我知道这项技术在iOS上是新的,但我并没有预料到会有如此严重的性能下降。



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

解决方案

为了获得最佳性能批量插入时,你不应该lis对于每个ad​​d语句中的事件,您应该附加到事务 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 added< br />; document.getElementById(output)。innerHTML + =结束时间:+(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打开db< br />;}  

 < div id =output>< / div>  


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?

解决方案

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>

这篇关于插入时IndexedDB会变慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆