国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

JS提高效率的經驗訪談

2024-05-06 15:45:15
字體:
來源:轉載
供稿:網友

JavaScript是一種非常靈活的語言,我們可以隨心所欲地編寫各種類型的代碼,不同類型的代碼執行效率的也是不一樣的,不過在開發過程中,有許多方法可以分散地提高代碼性能,那么JS提交效率的經驗訪談大家都了解嗎?一起跟著錯新技術頻道小編的步伐來了解一下吧!

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

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

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

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

經過測試,我們會發現如下的情況或者說的結論,如果您的測試結果與我的不符,請說明原因,以便相互學習。

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

下面對癥下藥:

問題一

我們可以做的沒有其它的,只有盡可能少的HTML字符串,比如最基本的一個DIV,可以這樣寫

也可以這樣寫

,第二種就比第一種速度明顯要快的。如果還不行的話,請看下面這個方法對你是否合適

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

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

uploads/200608/07_194917_array_limit.png


利用這一些,我們可以把數據有效的值先取出來。如圖:

uploads/200608/07_194953_auto_limit.png


想想看。假如我們取一個數組,下標為10000,設生成一個autocomplete的節點HTML長度20(已經非常小了"

item

)。
匹配數據已知:有3000條數據
輸節字節數為:3000(asc碼)也就是3000*20=60000字節
而用limit方法,輸出為:10*20=200字節。
很明顯的差距!
之后我們便可以分步求解,即當滾動條出現,或者按下down(方向鍵)再動態的生成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;
}
有興趣的朋友也可以自己測一下,貼出數據,看看哪個效率更好。

問題二、
為什么我們還要循環來綁定事件呢?
還是由于問題一。
假設這樣寫
1)

never-online


還可以這樣寫
2)

never-online


document.getElementById("container").childNodes[0].onclick=function(){handlerClick()};
這樣也可以省掉一些字符串,從而節省字符串資源。但又需要把container的子元素再遍歷,所以也會花費時間,用第一種方法還是第二種?我建議還是用第一種,但最好把字符串減到最低,如:

never-online


大數據量情況下,還是越少字符越好,雖然代碼不怎么美觀。

問題三、
生成DIV時我們可以這樣生成
var div = document.createElement("DIV");
div.onclick=function(){};
//TODO
也可以這樣用字符串
var sHtml = "

val

";
當數量小時,第一種速度會比第二種快。但當達到一個數量級時,第二種要明顯比第一種快。總體來說第二種較好。因為第二種還可以更靈活,比如利用join,還有正則匹配。

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

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

uploads/200608/09_002205_match.png


3)寧可多次判斷,也不重復進行一次重新匹配。e.g:
input控件中第一次取到的值為:1,第二次按下的值為12
如果進行判斷的話,可以事件存儲一個值,也就是前一次按下的值。如上面的值1。第二次按下時沒有退格,即再在前面的值中加一個字符2,那么我們將在前面1中匹配出的數據中進行匹配。這樣可以大大的減輕循環的次數。
4)利用問題一中所寫的limit,將數據動態取出。這些能夠很好的解決HTML字符串過大的問題,但此方法控制不當的話,也會事得其反。
5) 利用range技巧來加入HTMLStr,也就是說,當一個HTML字符串太大時,再用innerHTML+=anotherHTMLStr,這樣的方法,也是會讓速度太慢,在IE中,我們可以用obj.insertAdjacentHTML("beforeEnd", anotherHTMLStr)這樣的方法來插入HTML,這個方法經過測試,比較穩定。利用limit再加上insertAdjacentHTML,會使得插入的HTML代碼速度更穩定,而在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;
}
};
}

后記:效率問題沒有一個完整的解決方法,只有實踐中根據需要而定。因此,上面的方法僅供您參考,如果你也有一些好的方法,可以在評論中寫下您的經驗,以便交流。

上文是錯新技術頻道小編為大家搜集到的相關介紹,希望對你了解JS提高效率的經驗訪談有所幫助!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 郯城县| 德江县| 大渡口区| 沿河| 青海省| 保德县| 平昌县| 甘肃省| 黎川县| 福泉市| 应城市| 潮州市| 新丰县| 庆云县| 卓资县| 吉木乃县| 东城区| 潼关县| 景德镇市| 青铜峡市| 桂林市| 桂平市| 平陆县| 梁山县| 曲水县| 高碑店市| 拉萨市| 昌吉市| 古交市| 奇台县| 武胜县| 邛崃市| 思茅市| 新津县| 北流市| 开原市| 梁河县| 五华县| 商城县| 米泉市| 新闻|