Append Outside of Loops
触动 DOM 会带来成本消耗。若要向 DOM 中添加大量元素,应当一次性添加所有元素,而不是一次添加一个元素。
示例:
$.each( myArray, function( i, item ) {
var newListItem = "<li>" + item + "</li>";
$( "#ballers" ).append( newListItem );
});
一种常见的技术是利用文档片段。在循环的每次迭代中,将元素添加到片段中,而不是添加到 DOM 元素中。在循环结束之后,再将此片段添加到 DOM 元素中。
var frag = document.createDocumentFragment();
$.each( myArray, function( i, item ) {
var newListItem = document.createElement( "li" );
var itemText = document.createTextNode( item );
newListItem.appendChild( itemText );
frag.appendChild( newListItem );
});
$( "#ballers" )[ 0 ].appendChild( frag );
另一种简单的技术,在循环的每次迭代期间构建一个字符串。在循环结束之后,设置 DOM 元素的 HTML 内容为此字符串。
var myHtml = "";
$.each( myArray, function( i, item ) {
myHtml += "<li>" + item + "</li>";
});
$( "#ballers" ).html( myHtml );
Cache Length During Loops
在 for 循环中,不要在循环的每次迭代期间访问数组的长度属性;应当在循环外来预存该属性。
var myLength = myArray.length;
for ( var i = 0; i < myLength; i++ ) {
// do stuff
}
Detach Elements to Work with Them
DOM 是缓慢的,尽量不要操作它们。jQuery 在1.4版本之后引入 detach() 方法来解决这个问题,允许在处理该元素时,将其从 DOM 中移除。
var table = $( "#myTable" );
var parent = table.parent();
table.detach();
// ... add lots and lots of rows to table
// 处理完成之后,再加回
parent.append( table );
Don't Act on Absent Elements
// Bad: This runs three functions before it
// realizes there's nothing in the selection
$( "#nosuchthing" ).slideUp();
// Better:
var elem = $( "#nosuchthing" );
// 判断是否存在选项
if ( elem.length ) {
elem.slideUp();
}
// Best: Add a doOnce plugin.
jQuery.fn.doOnce = function( func ) {
this.length && func.apply( this );
return this;
}
$( "li.cartitems" ).doOnce(function() {
// make it ajax! \o/
});
Optimize Selectors
jQuery Extensions
尽可能使选择器中避免包含 jQuery Extensions。
// Slower (the zero-based :even selector is a jQuery extension)
$( "#my-table tr:even" );
// Better, though not exactly equivalent
$( "#my-table tr:nth-child(odd)" );
Avoid Excessive Specificity
使选择器,通过尽量少的层级来寻找元素。
$( ".data table.attendees td.gonzalez" );
// Better: Drop the middle if possible.
$( ".data td.gonzalez" );
ID-Based Selectors
选择器中使用 ID 更加保险。
// A Fast:
$( "#container div.robotarm" );
// B Super-fast:
$( "#container" ).find( "div.robotarm" );
途径 A,jQuery 通过 document.querySelectorAll() 来查询 DOM;途径 B,jQuery 通过 document.getElementById() 来查询 DOM,即使速度的提升会被后续的 find() 方法减低,此种方法查询元素也更快。
Tips for Older Browers
为了支持老旧的浏览器,例如:IE8 或更早的版本,需要考虑下方的小技巧。
Specificity
具体的指定在选择器的右侧,不太具体的在选择器的左侧。若可能的话,在最右侧的选择器中使用 tag.class,而在左侧的选择器仅使用标记或 .class。
// Unoptimized:
$( "div.data .gonzalez" );
// Optimized:
$( ".data td.gonzalez" );
Avoid the Universal Selector
通用选择器效能会非常慢。
$( ".buttons > *" ); // Extremely expensive.
$( ".buttons" ).children(); // Much better.
$( ":radio" ); // Implied universal selection.暗指通用选择
$( "*:radio" ); // Same thing, explicit now.更加明确
$( "input:radio" ); // Much better.
Use Stylesheets for Changing CSS on Many Elements
若使用 .css() 方法改变超过20个元素的 CSS,考虑在页面中加入 style 标签,会带来近 60% 的速度提升。
// Fine for up to 20 elements, slow after that:
$( "a.swedberg" ).css( "color", "#0769ad" );
// Much faster:
$( "<style type=\"text/css\">a.swedberg { color: #0769ad }</style>")
.appendTo( "head" );
Don't Treat jQuery as a Black Box
将源代码视为程式说明,经常参考这个文档:jQuery Core