做好七件事帮你提升jQuery的性能


Posted in Javascript onFebruary 06, 2014

1. Append Outside of Loops

凡是触及到DOM都是有代价的。如果你向DOM当中附加大量的元素,你会想一次性将它们全部附加进来,而不是分多次进行。当在循环当中附加元素就会产生一个常见的问题。

$.each( myArray, function( i, item ) {
    var newListItem = "<li>" + item + "</li>";
    $( "#ballers" ).append( newListItem );
});

一个常用的技巧是利用文档片段(document fragment)。在循环的每一次迭代当中,将元素附加到片段而不是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 );

当然还有其它一些技巧可以供你尝试。一个名为 jsperf 的站点为测试这些性能提供了一条好的出路。该网站允许你使用基准测试每一个技巧,并将其跨平台的性能测试结果可视化的展现出来。

2. Cache Length During Loops

在for循环当中,不要每次都访问数组的 length 属性;应当事先将其缓存起来。

var myLength = myArray.length;
for ( var i = 0; i < myLength; i++ ) {
    // do stuff
}

3. 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 );

4. Don't Act on Absent Elements

如果你正打算在一个空的选择器上运行大量的代码,jQuery并不会给予任何的提示 -- 它将会继续的执行,就像是没有发生任何的错误。必须由你来验证选择器包含了多少元素。

// Bad: This runs three functions before it
// realizes there's nothing in the selection
$( "#nosuchthing" ).slideUp();
// Better:
var $mySelection = $( "#nosuchthing" );
if ( $mySelection.length ) {
    $mySelection.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/

});

本指南特别适用于那些当选择器不包含元素时还需要大量的开销的 jQuery UI 部件。

5. Optimize Selectors

选择器的优化和过去比起来并不是那么的重要,因为很多浏览器都实现了 document.querySelectorAll() 方法并且jQuery将选择器的负担转移到了浏览器上面。但是仍然有一些技巧需要铭记在心。

基于ID的选择器

以一个ID作为选择器的开始总是最好的。

 // Fast:
 $( "#container div.robotarm" ); // Super-fast:
 $( "#container" ).find( "div.robotarm" );

采用 .find() 方法的方式将更加的快速,因为第一个选择器已经过处理,而无需通过嘈杂的选择器引擎 -- ID-Only的选择器已使用 document.getElementById() 方法进行处理,之所以快速,是因为它是浏览器的原生方法。

特异性

尽量详细的描述选择器的右侧,对于左侧则应反其道而行之。

 // Unoptimized:
 $( "div.data .gonzalez" ); // Optimized:
 $( ".data td.gonzalez" );

尽量在选择器的最右侧使用 tag.class 的形式来描述选择器,而在左侧则尽量只使用 tag 或者 .class 。

避免过度使用特异性

 $( ".data table.attendees td.gonzalez" ); // Better: Drop the middle if possible.
 $( ".data td.gonzalez" );

去讨好“DOM”总是有利于提升选择器的性能,因为选择器引擎在搜寻元素时无需进行太多的遍历。

避免使用通用选择器

如果一个选择器明确或暗示它能在不确定的范围内进行匹配将会大大影响性能。

 $( ".buttons > *" ); // Extremely expensive.
 $( ".buttons" ).children(); // Much better. $( ".category :radio" ); // Implied universal selection.
 $( ".category *:radio" ); // Same thing, explicit now.
 $( ".category input:radio" ); // Much better.
 Use Stylesheets for Changing CSS on Many Elements

假如你使用 .css() 方法来改变超过20个元素的CSS,应当考虑为页面添加一个样式标签作为替代,这样做可以提升将近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的源码当成文档,可以把它(http://bit.ly/jqsource)保存在你的收藏夹内,经常的查阅参考。

Javascript 相关文章推荐
利用404错误页面实现UrlRewrite的实现代码
Aug 20 Javascript
前端开发必须知道的JS之原型和继承
Jul 06 Javascript
jquery focus(fn),blur(fn)方法实例代码
Dec 16 Javascript
jquery实现像栅栏一样左右滑出式二级菜单效果代码
Aug 24 Javascript
jQuery实现类似标签风格的导航菜单效果代码
Aug 25 Javascript
Jquery基础之事件操作详解
Jun 14 Javascript
超全面的vue.js使用总结
Feb 12 Javascript
微信小程序实现传参数的几种方法示例
Jan 10 Javascript
Vuex中mutations与actions的区别详解
Mar 01 Javascript
vue移动端下拉刷新和上拉加载的实现代码
Sep 08 Javascript
js实现开关灯效果
Mar 30 Javascript
vue项目中在可编辑div光标位置插入内容的实现代码
Jan 07 Javascript
为开发者准备的10款最好的jQuery日历插件
Feb 04 #Javascript
javascript简单性能问题及学习笔记
Feb 04 #Javascript
JavaScript初学者建议:不要去管浏览器兼容
Feb 04 #Javascript
21个值得收藏的Javascript技巧
Feb 04 #Javascript
Javascript 按位与运算符 (&amp;)使用介绍
Feb 04 #Javascript
Javascript 按位与赋值运算符 (&amp;=)使用介绍
Feb 04 #Javascript
Javascript 按位左移运算符使用介绍(
Feb 04 #Javascript
You might like
laravel学习教程之关联模型
2016/07/30 PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
2018/05/23 PHP
PHP 命名空间和自动加载原理与用法实例分析
2020/04/29 PHP
PHP程序员简单的开展服务治理架构操作详解(一)
2020/05/14 PHP
ExtJS 2.0 实用简明教程之布局概述
2009/04/29 Javascript
dtree 网页树状菜单及传递对象集合到js内,动态生成节点
2012/04/14 Javascript
jquery.bgiframe.js在IE9下提示INVALID_CHARACTER_ERR错误
2013/01/11 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
2014/02/26 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
2014/10/17 Javascript
使用jquery动态加载js文件的方法
2014/12/24 Javascript
JS实现单击输入框弹出选择框效果完整实例
2015/12/14 Javascript
jquery点击展示与隐藏更多内容
2016/12/03 Javascript
详解js树形控件—zTree使用总结
2016/12/28 Javascript
简单实现JavaScript弹幕效果
2020/08/27 Javascript
Vue.js组件间的循环引用方法示例
2017/12/27 Javascript
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
2018/11/28 Javascript
3分钟读懂移动端rem使用方法(推荐)
2019/05/06 Javascript
vuex入门最详细整理
2020/03/04 Javascript
[38:21]2018DOTA2亚洲邀请赛3月30日 小组赛A组 LGD VS Newbee
2018/03/31 DOTA
教大家使用Python SqlAlchemy
2016/02/12 Python
python装饰器实例大详解
2017/10/25 Python
python机器学习库scikit-learn:SVR的基本应用
2019/06/26 Python
python 实现多线程下载m3u8格式视频并使用fmmpeg合并
2019/11/15 Python
python使用正则表达式去除中文文本多余空格,保留英文之间空格方法详解
2020/02/11 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
2020/06/05 Python
Python __slots__的使用方法
2020/11/15 Python
python Xpath语法的使用
2020/11/26 Python
css3打造一款漂亮的卡哇伊按钮
2013/03/20 HTML / CSS
Bootstrap 学习分享
2012/11/12 HTML / CSS
外包公司软件测试工程师
2014/11/01 面试题
大学军训感言1500字
2014/03/09 职场文书
倡议书格式
2014/08/30 职场文书
2014年仓库管理工作总结
2014/12/17 职场文书
女性励志书籍推荐
2019/08/19 职场文书
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python
Python使用openpyxl模块处理Excel文件
2022/06/05 Python