今天無意發現jquery的一個以前的誤導

時間都瘋了,你知道嗎?發表於2016-02-29

本文提供即刻提升你的指令碼效能的十個步驟。不用擔心,這並不是什麼高深的技巧。人人皆可運用!這些技巧包括: 
使用最新版本 
合併、最小化指令碼 
用for替代each 
用ID替代class選擇器 
給選擇器指定前後文 
建立快取 
避免DOM操作 
避免使用concat(),利用join()處理長字串 
返回false值 
利用小抄和參考文件 
使用最新版本 
jQuery一直處於不斷的開發和改進過程中。 John 和他的團隊不斷研究著提升程式效能的新方法。 
一點題外話,幾個月前他還發布了Sizzle,一個據說能在Firefox中把程式效能提升3倍的JS選擇器庫。 
如果你不想時刻關注是否有新版本,然後再花時間下載上傳,Google 就又能幫你一把了。他們的伺服器上儲存了大量Ajax庫供您選擇。 

.程式碼如下:

<!-- 利用一個簡單的script標籤呼叫API --> 
<script type="text/javascript" src="http://www.google.com/jsapi"></script> 
<script type="text/javascript"> 
/* 載入 jQuery v1.3.2 */ 
google.load ("jquery", "1.3.2", {uncompressed: false}); 
/* 載入完成後彈出訊息 */ 
function onLoad () { 
alert ("jQuery + Google API!"); 

google.setOnLoadCallback (onLoad); 
</script> 


另一個更為簡單快速的方法是直接使用指令碼連結。如果要使用特定版本的jQuery,你可以使用上面的方法;如果想直接使用最新版,下面這句程式碼就夠了: 

.程式碼如下:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script> 


特定版本的還可以這樣載入: 

.程式碼如下:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 


合併、最小化指令碼 
大部分瀏覽器都不能同時處理多個指令碼檔案,所以它們都是排隊載入——載入時間也相應地延長了。 
考慮到你網站的每個頁面都會載入這些指令碼,你應該考慮把它們放到單個檔案中,然後利用壓縮工具(比如 Dean Edwards 的這款)把它們最小化。更小的檔案無疑將帶來更快的載入速度。 
JavaScript和CSS壓縮的目的是在保持指令碼的執行效能的同時,減少資料傳遞的位元組數(可以通過減小原始檔案,也可以利用gzip。大多數產品級的網路伺服器都把gzip作為HTTP協議的一部分)。引自 YUI compressor,一款 jQuery官方推薦的壓縮指令碼的工具。 
用for替代each 
原生函式總是比輔助元件更快。 
如果遇到需要遍歷物件的情況(如從遠端接收的JSON物件),你最好重寫你的(JSON)物件為一個陣列,陣列的迴圈處理要容易些。 
利用Firebug,我們能測定每個函式的執行時間。 

.程式碼如下:

var array = new Array (); 
for (var i=0; i<10000; i++) { 
array[i] = 0; 

console.time('native'); //原生for函式 
var l = array.length; 
for (var i=0; i<10000; i++) { 


 
上面的結果顯示原生程式碼只需2毫秒就做到的事,利用jQuery的each方法需要26毫秒。而且這還只是我在本機上測試一個基本上啥也沒做的函式的結果,當遇到更復雜的情況,例如設定css屬性或DOM操作時,時間差異肯定更大。 
用ID替代class選擇器 
利用ID選擇物件要好得多,因為這時jQuery會使用瀏覽器的原生函式getElementByID()來獲取物件,查詢速度很快。 
因此,比起利用那些方便的css選擇技巧,使用更為複雜的選擇器也是值得的(jQuery也為我們提供了複雜選擇器)。你也可以手工書寫自己的選擇器(其實比你想象中簡單),或者為你想要選擇的元素指定一個有ID的容器。 

.程式碼如下:

//下例建立一個列表並且填充條目內容 
//然後每個條目都被選擇一次 
//首先使用class選擇 
console.time('class'); 
var list = $('#list'); 
var items = ' 
'; 
for (i=0; i<1000; i++) { 
items += ' 
item 
'; 

items += ' 
'; 
list.html (items); 
for (i=0; i<1000; i++) { 
var s = $('.item' + i); 

console.timeEnd('class'); 
//然後利用ID選擇 
console.time('id'); 
var list = $('#list'); 
var items = ' 
'; 
for (i=0; i<1000; i++) { 
items += ' 
item 
'; 

items += ' 
'; 
list.html (items); 
for (i=0; i<1000; i++) { 
var s = $('#item' + i); 

console.timeEnd('id'); 


上面的例子很好地說明了不同選擇方式之間的顯著效能差異。請看下圖,利用class來做選擇,時間無限增大,甚至超過了五秒。 
給選擇器指定前後文 
jQuery的參考文件裡說:傳遞給jQuery() 原始DOM節點的前後文(如果沒有東西被傳遞,則前後文為整個文件)。目的是連同選擇器一起,實現更為準確的查詢。 
所以,如果你一定要利用class來指定目標,至少為選擇器指定上下文,以免jQuery費精力去遍歷整個DOM文件: 
與其這樣寫: 

.程式碼如下:

$('.class').css ('color' '#123456'); 


為選擇器加上前後文比較好(expression: 目標選擇器;context: 前後文): 

.程式碼如下:

$(expression, context) 


也就是說: 

.程式碼如下:

$('.class', '#class-container').css ('color', '#123456'); 


這樣做要快得多,因為它不用遍歷整個DOM。只要找到#class-container就好了。 
建立快取 
不要犯不斷重新選擇同一個東西的錯誤。你應該把你要處理的元素快取為一個變數。 
更不要在一個迴圈裡重複選擇同一個元素!這樣做十分影響速度! 

.程式碼如下:

$('#item').css('color', '#123456'); 
$('#item').html('hello'); 
$('#item').css('background-color', '#ffffff'); 
// 這樣寫更好 
$('#item').css('color', '#123456').html('hello').css('background-color', '#ffffff'); 
// 甚至這樣 
var item = $('#item'); 
item.css('color', '#123456'); 
item.html('hello'); 
item.css('background-color', '#ffffff'); 
// 遇到迴圈,這樣做非常不好 
console.time('no cache'); 
for (var i=0; i<1000; i++) { 
$('#list').append(i); 

console.timeEnd('no cache'); 
// 下面這樣要好得多 
console.time('cache'); 
var item = $('#list'); 
for (var i=0; i<1000; i++) { 
item.append (i); 

console.timeEnd('cache'); 


避免DOM操作 
DOM操作應該越少越好,因為諸如prepend(),append(),after()的插入動作都很費時。上面的例子如果用html()會更快: 

.程式碼如下:

var list = ''; 
for (var i=0; i<1000; i++) { 
list += ' 
'+i+' 
'; 

('#list').html (list); 


避免使用concat(),利用join()處理長字串 
聽起來可能挺奇怪,不過這樣做真的能提升速度,尤其是當連線特別長的字串時。先建立一個陣列,放入你想要串聯的東西。join()方法比字串的concat()函式要快得多。 

.程式碼如下:

var array = []; 
for (var i=0; i< =10000; i++) { 
array[i] = ' 
'+i+''; 

$('#list').html(array.join ('')); 


“ += 操作符更快——比把字串片段放到陣列中然後join起來還要快”,“作為字串緩衝(string buffer)的陣列在大部分瀏覽器中都比string.prototype.concat.apply方法效率更高,Windows下的Firefox 2.0.0.14例外。” — Tom Trenka 
返回false值 
您可能已經注意到,如果函式執行後不返回false,你就會被跳轉到頁面頂部。如果頁面較長,這種反應是很煩人的。 
所以,與其這樣: 

.程式碼如下:

$('#item').click (function () { 
// stuff here 
}); 


不如多加一句: 

.程式碼如下:

$('#item').click (function () { 
// stuff here 
return false; 
}); 


額外小貼士 – 小抄和參考文件 
 
這條建議並不直接提升函式的執行速度,不過如果你肯花時間在這上面,研究研究這些小抄和參考文件,你將來定能節約很多時間。 
請在手邊隨時放一張小抄以作快速參考。

相關文章