jQuery代码性能优化的10种方法


Posted in Javascript onJune 21, 2016

1、总是使用#id去寻找element.

在jQuery中最快的选择器是ID选择器 ($('#someid')). 这是因为它直接映射为JavaScript的getElementById()方法。
选择单个元素

<div id="content">

 <form method="post" action="/">

  <h2>Traffic Light</h2>

  <ul id="traffic_light">

   <li><input type="radio" class="on" name="light" value="red" /> Red</li>

   <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li>

   <li><input type="radio" class="off" name="light" value="green" /> Green</li>

  </ul>

  <input class="button" id="traffic_button" type="submit" value="Go" />

 </form>

</div>

选择button的性能不好的一种方式:

var traffic_button = $('#content .button');

取而代之的是直接选择button:

var traffic_button = $('#traffic_button');

选择多个元素

在我们讨论选择多个元素的时候,我们真正需要知道的是DOM的遍历和循环才是性能低下的原因。为了尽量减少性能损失, 总是使用最近的父ID去寻找。

var traffic_lights = $('#traffic_light input');

2、在Classes前面使用Tags

在jQuery中第二快的选择器就是Tag选择器 ($('head')). 而这是因为它直接映射到JavaScript的getElementsByTagName()方法。

<div id="content">

 <form method="post" action="/">

  <h2>Traffic Light</h2>

  <ul id="traffic_light">

   <li><input type="radio" class="on" name="light" value="red" /> Red</li>

   <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li>

   <li><input type="radio" class="off" name="light" value="green" /> Green</li>

  </ul>

  <input class="button" id="traffic_button" type="submit" value="Go" />

 </form>

</div>

总是在一个Class前面加上一个tag名字(记得从一个ID传下来)

var active_light = $('#traffic_light input.on');

注意:在jQuery里Class选择器是最慢的一个选择器;在IE中它循环整个DOM。可能的话尽量避免使用它。不要在ID前面 加Tags。例如,它会因为去循环所有的<div>元素去寻找ID为content的<div>,而导致很慢。

var content = $('div#content');

按照同样的思路,从多个ID传下来是冗余的。

var traffic_light = $('#content #traffic_light');

3、缓存jQuery对象

养成保存jQuery对象到一个变量上(就像上面的例子)的习惯。例如,不要这样做:

$('#traffic_light input.on).bind('click', function(){...});

$('#traffic_light input.on).css('border', '3px dashed yellow');

$('#traffic_light input.on).css('background-color', 'orange');

$('#traffic_light input.on).fadeIn('slow');

取而代之,首现保存jQuery变量到一个本地变量后,再继续你的操作。

var $active_light = $('#traffic_light input.on');
 
$active_light.bind('click', function(){...});
 
$active_light.css('border', '3px dashed yellow');
 
$active_light.css('background-color', 'orange');
 
$active_light.fadeIn('slow');

提示:使用$前辍表示我们的本地变量是一个jQuery包集。记住,不要在你的应该程序里出现一次以上的jQuery重复的选择操作。 额外提示:延迟存储jQuery对象结果。

如果你想在你的程序的其它地方使用jQuery结果对象(result object(s)),或者你的函数要执行多次,要把它缓存在一个全局范围的对象里。通过定义一个全局容器保存jQuery结果对象,就可以在其它的函数里引用它。

// Define an object in the global scope (i.e. the window object)

window.$my ={

 // Initialize all the queries you want to use more than once

 head : $('head'),

 traffic_light : $('#traffic_light'),

 traffic_button : $('#traffic_button')};

function do_something(){

 // Now you can reference the stored results and manipulate them

 var script = document.createElement('script');

 $my.head.append(script);

 // When working inside functions, continue to save jQuery results

 // to your global container.

 $my.cool_results = $('#some_ul li');

 $my.other_results = $('#some_table td');

 // Use the global functions as you would a normal jQuery result

 $my.other_results.css('border-color', 'red');

 $my.traffic_light.css('border-color', 'green');

}

4、更好的利用链

前面的例子也可以这样写:

var $active_light = $('#traffic_light input.on');

$active_light.bind('click', function(){...})

 .css('border', '3px dashed yellow')

 .css('background-color', 'orange')

 .fadeIn('slow');

这样可以让我们写更少的代码,使JavaScript更轻量。

5、使用子查询

jQuery允许我们在一个包集上附加其它的选择器。因为我们已经在本地变量里保存了父对象这样会减少以后在选择器上的性能开销。

<div id="content">

 <form method="post" action="/">

  <h2>Traffic Light</h2>

  <ul id="traffic_light">

   <li><input type="radio" class="on" name="light" value="red" /> Red</li>

   <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li>

   <li><input type="radio" class="off" name="light" value="green" /> Green</li>

  </ul>

  <input class="button" id="traffic_button" type="submit" value="Go" />

 </form>

</div>

例如,我们可以利用子查询缓存active和inactive lights以便后面的操作。

var $traffic_light = $('#traffic_light'), 

$active_light = $traffic_light.find('input.on'), 

$inactive_lights = $traffic_light.find('input.off');

提示:可以用逗号隔开一次定义多个本地变量,这样可以节省一些字节。

6、限制直接对DOM操作

DOM操作的基本做法是在内存中创建DOM结构,然后再更新DOM结构。这不是jQuery最好的做法,但对JavaScript来讲是高效的。直接操作DOM结构性能是低下的。 例如,如果你需要动态创建一列元素,不要这样做:

var top_100_list = [...], // assume this has 100 unique strings 

$mylist = $('#mylist'); // jQuery selects our <ul> element

for (var i=0, l=top_100_list.length; i<l; i++){ 

 $mylist.append('<li>' + top_100_list[i] + '</li>');

}

取而代之,我们希望在插入DOM结构之前先在一个字符串里创建一套元素。
代码

var top_100_list = [...], // assume this has 100 unique strings 

$mylist = $('#mylist'), // jQuery selects our <ul> element 

top_100_li = ""; // This will store our list items

for (var i=0, l=top_100_list.length; i<l; i++){

 top_100_li += '<li>' + top_100_list[i] + '</li>';

}

$mylist.html(top_100_li);

更快的做法,在插入DOM结构之前我们应该总是在一个父节点里包含许多元素

var top_100_list = [...], // assume this has 100 unique strings 

$mylist = $('#mylist'), // jQuery selects our <ul> element 

top_100_ul = '<ul id="#mylist">'; // This will store our entire unordered list

for (var i=0, l=top_100_list.length; i<l; i++){

 top_100_ul += '<li>' + top_100_list[i] + '</li>';

}

top_100_ul += '</ul>'; // Close our unordered list

$mylist.replaceWith(top_100_ul);

如是你照着上面的做了还是对性能有些迷惑的话,可以参考以下内容:

* 试一下jQuery提供的Clone()方法。Clone()方法创建节点数的拷贝,随后你可以在这个副本中进行操作。

* 使用DOM DocumentFragments. As the creator of jQuery points out, 比直接操作DOM性能上更好. 先创建你需要的结构(就像我们上面用一个字符串做的一样), 然后使用jQuery的 insert or replace methods.

7、事件委托(又名:冒泡事件)

除非特别说明,每一个JavaScript事件(如click, mouseover 等)在DOM结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的大型form,当input被选择的时候我们想绑定一个class name。像这样的帮定是效率低下的:

$('#myList li).bind('click', function(){

 $(this).addClass('clicked'); // do stuff

});

反而,我们应该在父级侦听click事件。

$('#myList).bind('click', function(e){

 var target = e.target, // e.target grabs the node that triggered the event.

  $target = $(target); // wraps the node in a jQuery object

 if (target.nodeName === 'LI') {

  $target.addClass('clicked');  // do stuff

 }

});

父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。如果你发现自己把一个event listener帮定到很多个element上,那么你这种做法是不正确的。

8、消除查询浪费

虽然jQuery对没有找到任何匹配的elements处理的很好,但是它还是需要花费时间去查找的。如果你的站点有一个全局的JavaScript,你可能会把每个jQuery function都放在 $(document).ready(function(){ // all my glorious code })里。 不要这样做。只去放一些页面上适合用到的function。这样做最有效的方式是你的模板可以完全控制任何时候或者地方执行JavaScript以内联脚 本的方式初始化function。例如,在你的“article”页面模板里,你可能在body标签关闭之前包含以下代码

<script type="text/javascript>mylib.article.init();</script></body& gt;如果你的页面模板包含多种有可能在页面或者不在页面上的模块,或者为了可视化效果你需要它们稍后再初如化,你应该在这些模块之后立即放置初如化函数。

<ul id="traffic_light">

 <li><input type="radio" class="on" name="light" value="red" /> Red</li>

 <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li>

 <li><input type="radio" class="off" name="light" value="green" /> Green</li>

</ul>



<script type="text/javascript>mylib.traffic_light.init();</script>

你的全局JavaScript库看起来应该是这样的:

var mylib ={

 article_page : {

  init : function()  {

   // Article page specific jQuery functions. 

  }

 }, 

 traffic_light : {

  init : function()  {

   // Traffic light specific jQuery functions. 

  }

 }

}

9、遵从$(windows).load

有 一种诱惑会使jQuery开发者hook所有事情到 $(document).ready 这个虚伪的事件里。毕竟在大多数例子里都可以看到这样使用。虽然$(document).ready 非常有用,它在页面呈现时发生,虽然其它对象还在下载中。如果你发现你的页面在下载中停顿,就有可能是$(document).ready 引起的。你可以通过把jQuery functions帮定到$(window).load事件来减少下面下载时的CPU使用率,它是在所有HTML(包括iframe内容)都下载完以后才 去调用所有对象的。

$(window).load(function(){

 // jQuery functions to initialize after the page has loaded.

});

多余的功能,如拖拽、帮定可视化效果和动画、预读取图片等,使用这种方法比较好。

10、压缩JS

虽然和jQuery无关,但在这里也要提一下。使JavaScript函数和变量变得可读是一个趋势,这对开发者来讲是必不可少的,但对普通用户来 讲没有任何关系。不用什么借口,是时候把JS压缩纳入我们的工作流程中来了。注释你的代码,在投放到生产环境之前找一个压缩工具进行压缩。使用 YUICompressor 压缩你代码中多余的浪费的字节。根据我们的经验,它可以安全的把JavaScript压缩的尽可能小,而不会多占用CPU。小提示:为了在 YUICompressor里最大化压缩,应该这样这样定义变量(例如:var my_long_variable_name;)

学习和最有效的使用jQuery,最好的方法就是去查jQuery的文档和手册了。

以上就是本文的全部内容,了解更多jQuery的语法,大家可以查看:《jQuery 1.10.3 在线手册》,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript Object与Function使用
Jan 11 Javascript
DWZ刷新dialog解决方法
Mar 03 Javascript
asp.net中System.Timers.Timer的使用方法
Mar 20 Javascript
JavaScript获取当前日期是星期几的方法
Apr 06 Javascript
js实现支持手机滑动切换的轮播图片效果实例
Apr 29 Javascript
浅谈JavaScript的Polymer框架中的behaviors对象
Jul 29 Javascript
JS实现可拖曳、可关闭的弹窗效果
Sep 26 Javascript
js实现PC端根据IP定位当前城市地理位置
Feb 22 Javascript
Node+Express+MongoDB实现登录注册功能实例
Apr 23 Javascript
详解webpack require.ensure与require AMD的区别
Dec 13 Javascript
vue实现tab切换外加样式切换方法
Mar 16 Javascript
JavaScript中arguments和this对象用法分析
Aug 08 Javascript
JS实现兼容各种浏览器的获取选择文本的方法【测试可用】
Jun 21 #Javascript
JS实现兼容各种浏览器的高级拖动方法完整实例【测试可用】
Jun 21 #Javascript
JavaScript检测原始值、引用值、属性
Jun 20 #Javascript
Js 获取当前函数参数对象的实现代码
Jun 20 #Javascript
JS实现鼠标框选效果完整实例
Jun 20 #Javascript
javascript事件冒泡简单示例
Jun 20 #Javascript
JS实现的打字机效果完整实例
Jun 20 #Javascript
You might like
php与mysql建立连接并执行SQL语句的代码
2011/07/04 PHP
php比较两个字符串长度的方法
2015/07/13 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
PHP实现的用户注册表单验证功能简单示例
2019/02/25 PHP
Jquery 基础学习笔记
2009/05/29 Javascript
动态的改变IFrame的高度实现IFrame自动伸展适应高度
2012/12/28 Javascript
基于Jquery制作图片文字排版预览效果附源码下载
2015/11/18 Javascript
jQuery AjaxUpload 上传图片代码
2016/02/02 Javascript
jQuery购物车插件jsorder用法(支持后台处理程序直接转换成DataTable处理)
2016/06/08 Javascript
Node.js与MySQL交互操作及其注意事项
2016/10/05 Javascript
jquery拖动改变div大小
2017/07/04 jQuery
vue使用技巧及vue项目中遇到的问题
2018/06/04 Javascript
JS中的const命令你真懂它吗
2020/03/08 Javascript
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
浅谈对yield的初步理解
2017/05/29 Python
Python实现完整的事务操作示例
2017/06/20 Python
python实现生命游戏的示例代码(Game of Life)
2018/01/24 Python
深入理解Django自定义信号(signals)
2018/10/15 Python
python分块读取大数据,避免内存不足的方法
2018/12/10 Python
django多个APP的urls设置方法(views重复问题解决)
2019/07/19 Python
python模块和包的应用BASE_PATH使用解析
2019/12/14 Python
Python简单实现区域生长方式
2020/01/16 Python
Python 下载Bing壁纸的示例
2020/09/29 Python
Python的logging模块基本用法
2020/12/24 Python
CSS3实现鼠标悬停显示扩展内容
2016/08/24 HTML / CSS
前端canvas水印快速制作(附完整代码)
2019/09/19 HTML / CSS
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
伦敦哈德森鞋:Hudson Shoes
2018/02/06 全球购物
美国地毯购买网站:Rugs USA
2019/02/23 全球购物
Kiwi.com中国:找到特价机票并发现新目的地
2019/10/27 全球购物
网络程序员自荐信
2014/01/25 职场文书
我爱读书演讲稿
2014/05/07 职场文书
党员检讨书
2014/10/13 职场文书
小学生暑假生活总结
2015/07/13 职场文书
vite+vue3.0+ts+element-plus快速搭建项目的实现
2021/06/24 Vue.js