亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS效率個人經(jīng)驗談(8-15更新),加入range技巧

 更新時間:2007年01月09日 00:00:00   作者:  
首先,要謝謝CSDN hbhbhbhbhb1021(天外水火(我要多努力))和cuixiping(無心)的提醒。我會抽空把IE專有的方法如:insertAdjacentHTML的速度也給測出來看看是否合適大量數(shù)據(jù)時IE下,不用innerHTML的速度。
這里的主要測試不是指生成數(shù)據(jù)時的速度,指的是匹配速度 ,例如
我這里的匹配速度
我測的10000條數(shù)據(jù),有效數(shù)據(jù)為1000-1100條,輸出復(fù)雜的HTML,速度為360ms左右,方法為 正則匹配Match(有循環(huán))
希望貼出您的測試數(shù)據(jù)。
行innerHTML和insertAdjacentHTML速度的測試,比均結(jié)果相差不會大于20ms(平均速度),在IE中insertAdjacentHTML速度還是很快的,在Mozilla下是得不償失的。

可以點擊這里進行簡單的匹配測試
點擊這里進行innerHTML和insertAdjacentHTML速度的測試,可以兼容Mozilla的

寫這篇文章,其間我也是刪刪減減的,所以語句也不怎么通順,看的朋友也就辛苦了一些了。

本文主要是出于有朋友使用我原來寫的autocomplete的JS控件。當數(shù)據(jù)量大的時候,會出現(xiàn)效率極其慢的情況,我在這段時間做出的一些測試也及一些經(jīng)驗,與大家分享,如果有錯的地方,還請指出。

經(jīng)過測試,我們會發(fā)現(xiàn)如下的情況或者說的結(jié)論,如果您的測試結(jié)果與我的不符,請說明原因,以便相互學(xué)習(xí)。

1)當一個較大的HTML字符串給到obj.innerHTML時會出現(xiàn)麻煩。也就是說當一個較大的字符串在賦予一個Element的innerHTML時,這個過程將可能是我們無法容忍的。(而事實上這并非JS的錯,而確實是String數(shù)據(jù)量太多)
2)用拼合字符串的方法可以使效率提高,在字符串較大時,2)的情況仍然出現(xiàn)。超過一定的數(shù)量,速度會明顯慢下來。
3)正則匹配的方法會比平常遍歷的方法要高效一些。
4)在執(zhí)行過程中,綁定事件的時間會花費更多一些。測試在1w條數(shù)據(jù)情況下,大約是匹配以及生成HTML數(shù)據(jù)的30倍,也就是說生成數(shù)據(jù)總花費100ms,而綁定事件則需要3000ms。
5)總體來說。IE的速度要比Mozilla要慢(我用的是Firefox1.5做的測試)。
6)大數(shù)據(jù)量時,不要用DOM生成Element。
7)非JS內(nèi)置方法,也許會引發(fā)很多時間過多重復(fù)的勞動而且可能事得其反。建議盡可能利會內(nèi)置方法。
總結(jié)問題:
一、在把字符串給到innerHTML上。
二、循環(huán)綁定事件所花費時間。
三、生成我們需要的DIV所花時間。
四、不同的瀏覽器問題。

下面對癥下藥:

問題一

我們可以做的沒有其它的,只有盡可能少的HTML字符串,比如最基本的一個DIV,可以這樣寫
<div style="height:20px; font:9pt Verdana;"></div>也可以這樣寫<div class="c1"></div>,第二種就比第一種速度明顯要快的。如果還不行的話,請看下面這個方法對你是否合適

在做程序的時候突然想起來51js上PK tree,一位版主所寫的一棵樹,1百萬的一個節(jié)點,動態(tài)載入。只需要不到1秒。毫無疑問,肯定是取巧了,因為只要只生tree的html就是一個很大的數(shù)量。這個樹的特別的地方就是生成樹時,并非把1百萬的節(jié)點都一次生成innerHTML,而是只生成在視角范圍內(nèi)的節(jié)點,當滾動條向下滾的時候,才動態(tài)的再生成樹節(jié)點。這個方法至少我覺得思想很開闊,很有價值。

我們所知道,mySQL數(shù)據(jù)庫里取數(shù)據(jù)可以這么取。SELECT * FROM table limit 0,100,意思是只取數(shù)據(jù)庫中的0-100條數(shù)據(jù)。說到這里可能有些朋友也想到了,在JS中,我們可以利用這個方法來取數(shù)據(jù),將一個數(shù)組看作是一個表。只是單純的數(shù)據(jù)表,非二維表。如圖
uploads/200608/07_194917_array_limit.png

利用這一些,我們可以把數(shù)據(jù)有效的值先取出來。如圖:
uploads/200608/07_194953_auto_limit.png

想想看。假如我們?nèi)∫粋€數(shù)組,下標為10000,設(shè)生成一個autocomplete的節(jié)點HTML長度20(已經(jīng)非常小了"<div class="out">item</div>)。
匹配數(shù)據(jù)已知:有3000條數(shù)據(jù)
輸節(jié)字節(jié)數(shù)為:3000(asc碼)也就是3000*20=60000字節(jié)
而用limit方法,輸出為:10*20=200字節(jié)。
很明顯的差距!
之后我們便可以分步求解,即當滾動條出現(xiàn),或者按下down(方向鍵)再動態(tài)的生成innerHTML。
8-13更新:測了一下,用自己寫的limit的速度,和自帶的Array.slice的速度比了一下,速度差不多,而且有的時候還比slice的速度還要快一些。
Array.prototype.limit = function(l, h) {
var _a = this; var ret = [];
l = l<0?0:l; h = h>_a.length?_a.length:h;
for (var i=0; i<_a.length; i++) {
if (i>=l && i<=h) ret[ret.length] = _a[i];
if (i>h) break;
}; return ret;
}
有興趣的朋友也可以自己測一下,貼出數(shù)據(jù),看看哪個效率更好。

問題二、
為什么我們還要循環(huán)來綁定事件呢?
還是由于問題一。
假設(shè)這樣寫
1)
<div id="container">
<div onclick="handlerClick()">never-online</div>
</div>
還可以這樣寫
2)
<div id="container">
<div>never-online</div>
</div>
document.getElementById("container").childNodes[0].onclick=function(){handlerClick()};
這樣也可以省掉一些字符串,從而節(jié)省字符串資源。但又需要把container的子元素再遍歷,所以也會花費時間,用第一種方法還是第二種?我建議還是用第一種,但最好把字符串減到最低,如:
<div id="container">
<div onclick="_c()">never-online</div>
</div>
大數(shù)據(jù)量情況下,還是越少字符越好,雖然代碼不怎么美觀。

問題三、
生成DIV時我們可以這樣生成
var div = document.createElement("DIV");
div.onclick=function(){};
//TODO
也可以這樣用字符串
var sHtml = "<div onclick=foo()>val</div>";
當數(shù)量小時,第一種速度會比第二種快。但當達到一個數(shù)量級時,第二種要明顯比第一種快??傮w來說第二種較好。因為第二種還可以更靈活,比如利用join,還有正則匹配。

問題四、
這個問題也不容忽視的。每個browser有不同的特點,速度執(zhí)行也有不同,我個人覺得,這點和JS上優(yōu)化效率上是一樣的。
盡可能的利用瀏覽器本身的內(nèi)置方法,這樣大多數(shù)情況下也可以把效率提高。

那么如何能夠把腳本的效率提高起來呢?
1)用match匹配,一個aCache數(shù)組。循環(huán)match.length,并給aCache,之后用join(""),再給到innerHTML(此方法仍然需要循環(huán),而且需額外的一個數(shù)組做臨時數(shù)據(jù)存儲)
2)無需循環(huán),但必須在生成數(shù)據(jù)時也額外生成指定字符串。(此方法也需要額外的空間做臨時數(shù)據(jù))如圖:
uploads/200608/09_002205_match.png

3)寧可多次判斷,也不重復(fù)進行一次重新匹配。e.g:
input控件中第一次取到的值為:1,第二次按下的值為12
如果進行判斷的話,可以事件存儲一個值,也就是前一次按下的值。如上面的值1。第二次按下時沒有退格,即再在前面的值中加一個字符2,那么我們將在前面1中匹配出的數(shù)據(jù)中進行匹配。這樣可以大大的減輕循環(huán)的次數(shù)。
4)利用問題一中所寫的limit,將數(shù)據(jù)動態(tài)取出。這些能夠很好的解決HTML字符串過大的問題,但此方法控制不當?shù)脑挘矔碌闷浞础?BR>5) 利用range技巧來加入HTMLStr,也就是說,當一個HTML字符串太大時,再用innerHTML+=anotherHTMLStr,這樣的方法,也是會讓速度太慢,在IE中,我們可以用obj.insertAdjacentHTML("beforeEnd", anotherHTMLStr)這樣的方法來插入HTML,這個方法經(jīng)過測試,比較穩(wěn)定。利用limit再加上insertAdjacentHTML,會使得插入的HTML代碼速度更穩(wěn)定,而在Mozilla中,則要利用range的技巧來達到此目的,如下:
if (browser.isMozilla) {
 HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sHTML) {
 var df; var r = this.ownerDocument.createRange();
 switch (String(sWhere).toLowerCase()) {
 case "beforebegin":
 r.setStartBefore(this);
 df = r.createContextualFragment(sHTML);
 this.parentNode.insertBefore(df, this);
 break;
 case "afterbegin":
 r.selectNodeContents(this);
 r.collapse(true);
 df = r.createContextualFragment(sHTML);
 this.insertBefore(df, this.firstChild);
 break;
 case "beforeend":
 r.selectNodeContents(this);
 r.collapse(false);
 df = r.createContextualFragment(sHTML);
 this.appendChild(df);
 break;
 case "afterend":
 r.setStartAfter(this);
 df = r.createContextualFragment(sHTML);
 this.parentNode.insertBefore(df, this.nextSibling);
 break;
 }
 };
}
后記:效率問題沒有一個完整的解決方法,只有實踐中根據(jù)需要而定。因此,上面的方法僅供您參考,如果你也有一些好的方法,可以在評論中寫下您的經(jīng)驗,以便交流。

相關(guān)文章

最新評論