1. Append Outside of Loops凡是觸及到DOM都是有代價的。如果你向DOM當中附加大量的元素,你會想一次性將它們全部附加進來,而不是分多次進行。當在迴圈當中附加元素就會產生一個常見的問題。1 $.each( myArray, function( i, item ) {2 3 ....
1. Append Outside of Loops
凡是觸及到DOM都是有代價的。如果你向DOM當中附加大量的元素,你會想一次性將它們全部附加進來,而不是分多次進行。當在迴圈當中附加元素就會產生一個常見的問題。
1 $.each( myArray, function( i, item ) { 2 3 var newListItem = "<li>" + item + "</li>"; 4 5 $( "#ballers" ).append( newListItem ); 6 7 });
一個常用的技巧是利用文檔片段(document fragment)。在迴圈的每一次迭代當中,將元素附加到片段而不是DOM元素當中。當迴圈結束後,將片段附加到DOM元素當中即可。
1 var frag = document.createDocumentFragment(); 2 3 $.each( myArray, function( i, item ) { 4 5 var newListItem = document.createElement( "li" ); 6 var itemText = document.createTextNode( item ); 7 8 newListItem.appendChild( itemText ); 9 10 frag.appendChild( newListItem ); 11 12 }); 13 14 $( "#ballers" )[ 0 ].appendChild( frag );
另一個簡單的技巧是在迴圈的每次迭代當中,持續構建一個字元串。當迴圈結束後,將DOM元素的HTML設置成該字元串。
1 var myHtml = ""; 2 3 $.each( myArray, function( i, item ) { 4 5 myHtml += "<li>" + item + "</li>"; 6 7 }); 8 9 $( "#ballers" ).html( myHtml );
當然還有其它一些技巧可以供你嘗試。一個名為 jsperf 的站點為測試這些性能提供了一條好的出路。該網站允許你使用基準測試每一個技巧,並將其跨平臺的性能測試結果可視化的展現出來。
2. Cache Length During Loops
在for迴圈當中,不要每次都訪問數組的 length 屬性;應當事先將其緩存起來。
1 var myLength = myArray.length; 2 3 for ( var i = 0; i < myLength; i++ ) { 4 5 // do stuff 6 7 }
3. Detach Elements to Work with Them
操作DOM是緩慢的,因此你想儘可能減少對齊進行操作。jQuery在1.4版本當中引入了名為 detach() 的方法來幫助解決這一問題,它允許你在對元素進行操作時,將它們從DOM當中分離出來。
1 var $table = $( "#myTable" ); 2 var $parent = $table.parent(); 3 4 $table.detach(); 5 6 // ... add lots and lots of rows to table 7 8 $parent.append( $table );
4. Don’t Act on Absent Elements
如果你正打算在一個空的選擇器上運行大量的代碼,jQuery並不會給予任何的提示 -- 它將會繼續的執行,就像是沒有發生任何的錯誤。必須由你來驗證選擇器包含了多少元素。
1 // Bad: This runs three functions before it 2 // realizes there's nothing in the selection 3 $( "#nosuchthing" ).slideUp(); 4 5 // Better: 6 var $mySelection = $( "#nosuchthing" ); 7 8 if ( $mySelection.length ) { 9 10 $mySelection.slideUp(); 11 12 } 13 14 // Best: Add a doOnce plugin. 15 jQuery.fn.doOnce = function( func ) { 16 17 this.length && func.apply( this ); 18 19 return this; 20 21 } 22 23 $( "li.cartitems" ).doOnce(function() { 24 25 // make it ajax! \o/ 26 27 });
本指南特別適用於那些當選擇器不包含元素時還需要大量的開銷的 jQuery UI 部件。
5. Optimize Selectors
選擇器的優化和過去比起來並不是那麼的重要,因為很多瀏覽器都實現了 document.querySelectorAll() 方法並且jQuery將選擇器的負擔轉移到了瀏覽器上面。但是仍然有一些技巧需要銘記在心。
基於ID的選擇器
以一個ID作為選擇器的開始總是最好的。
1 // Fast: 2 $( "#container div.robotarm" ); 3 4 // Super-fast: 5 $( "#container" ).find( "div.robotarm" );
採用 .find() 方法的方式將更加的快速,因為第一個選擇器已經過處理,而無需通過嘈雜的選擇器引擎 -- ID-Only的選擇器已使用 document.getElementById() 方法進行處理,之所以快速,是因為它是瀏覽器的原生方法。
特異性
儘量詳細的描述選擇器的右側,對於左側則應反其道而行之。
1 // Unoptimized: 2 $( "div.data .gonzalez" ); 3 4 // Optimized: 5 $( ".data td.gonzalez" );
儘量在選擇器的最右側使用 tag.class 的形式來描述選擇器,而在左側則儘量只使用 tag 或者 .class 。
避免過度使用特異性
1 $( ".data table.attendees td.gonzalez" ); 2 3 // Better: Drop the middle if possible. 4 $( ".data td.gonzalez" );
去討好“DOM”總是有利於提升選擇器的性能,因為選擇器引擎在搜尋元素時無需進行太多的遍歷。
避免使用通用選擇器
如果一個選擇器明確或暗示它能在不確定的範圍內進行匹配將會大大影響性能。
1 $( ".buttons > *" ); // Extremely expensive. 2 $( ".buttons" ).children(); // Much better. 3 4 $( ".category :radio" ); // Implied universal selection. 5 $( ".category *:radio" ); // Same thing, explicit now. 6 $( ".category input:radio" ); // Much better.
6. Use Stylesheets for Changing CSS on Many Elements
假如你使用 .css() 方法來改變超過20個元素的CSS,應當考慮為頁面添加一個樣式標簽作為替代,這樣做可以提升將近60%的速度。
1 // Fine for up to 20 elements, slow after that: 2 $( "a.swedberg" ).css( "color", "#0769ad" ); 3 4 // Much faster: 5 $( "<style type=\"text/css\">a.swedberg { color: #0769ad }</style>") 6 .appendTo( "head" );
7. Don’t Treat jQuery as a Black Box
把jQuery的源碼當成文檔,可以把它(http://bit.ly/jqsource)保存在你的收藏夾內,經常的查閱參考。