1. 程式人生 > >createElement與innerHtml性能比較

createElement與innerHtml性能比較

track ++ reat rate http 寫法 例如 字符串 sdn

js中。動態加入html的方法大致就是兩種,一種是document.createElement等方法創建,然後使用Element.appendChild加入,或者是使用Element.innerHTML = sHTML的方式。兩種方法,顯然前面一種更加靈活,除了Element.appendChild方法外,還有insertBefore等等其它dom操作方式。這裏且不談靈活性,但就性能做一個探索。

比較的方式非常easy:

各生成10000次形如<div><span>性能測試</span> ......</div>的html,然後一次性放入body中。記錄此全過程,耗時時間,並執行10次,輸出耗時。

代碼例如以下:

	window.onload = function(){
		testPerformance(10,function(){
			document.body.appendChild(generateHtmlElement(10000));
		})
		testPerformance(10,function(){
			document.body.innerHTML = generateHtmlString(10000);
		})
	}
	
	function testPerformance(iTimes,fn){
		var iLastTime = null;
		var iTotalTime = 0;
		for(var i=1;i<=iTimes;++i){
			iLastTime = new Date().getTime();
			fn();
			var iCost = new Date().getTime() - iLastTime;
			console.log("第"+i+"次用時:"+iCost+"毫秒");
			iTotalTime+=iCost;
			document.body.innerHTML = "";
			iLastTime = new Date().getTime();
		}
		console.log("總用時:"+iTotalTime+"毫秒");
		console.log("平均用時:"+iTotalTime/iTimes+"毫秒");
	}
	
	/*
	 *使用document.createElement等dom方法生成元素<div><span>測試性能</span>....<div>
	 *times:生成div的數量
	 *return Element
	 */
	function generateHtmlElement(iTimes){
		var result = document.createElement("div");
		for(var i=0;i<iTimes;++i){
			var eDiv = document.createElement("div");
			
			for(var j = 0;j<10;++j){
				var eSpan = document.createElement("span");
				eSpan.appendChild(document.createTextNode("測試性能"));
				eDiv.appendChild(eSpan);
			}
			result.appendChild(eDiv);
		}
		return result;
	}
	/* 
   *使用字符串拼接的方式生成<div><span>測試性能</span>....<div>字符串
   *times:生成div的數量 
   *return string 
   */
	function generateHtmlString(iTimes){
		var sb = new StringBuilder ();
		
		for(var i=0;i<iTimes;++i){
			sb.append("<div>");
			for(var j = 0;j<10;++j){
				sb.append("<span>性能測試</span>");
			}
			sb.append("</div>");
		}
		return sb.toString();
	}
	
	function StringBuilder () {
     this.__asBuilder = [];
	}

	StringBuilder.prototype.clear = function(){
	     this.__asBuilder = [];//這樣的寫法要比this.__asBuilder.length = 0稍快,快多少。看數組的長度
	}
	
	StringBuilder.prototype.append = function(){
	     Array.prototype.push.apply(this.__asBuilder,arguments);//調用Array的push方法,這樣調用。使用append,能夠傳遞多個參數
	     return this;//這樣能夠實現append("a").append()的效果
	}
	
	StringBuilder.prototype.toString = function(){
	     return this.__asBuilder.join("");    
	}


拼接字符串的過程中,使用了一個自己定義類StringBuilder,以提升字符串拼接性能。

測試結果例如以下:

chrome下,差不太多,innerHTML稍好一些:

技術分享

Firefox中,innerHTML完爆createElement

技術分享

IE11,應該說,IE11,被chrome和Firefox完爆了技術分享

總結一下,單就性能而言,innerHTML都要比createElement創建元素在append進dom中快一些。在IE下。就差的更遠了。話說,IE,你怎麽這麽慢?。我測試方式有問題麽?!

createElement與innerHtml性能比較