jquery的show/hide性能测试
这篇文章是jQuery各种 show/hide方式的性能测试。作者之所以测试这个源于Robert Duffy在SanFrancisco举行的jQuery大会上的一句话:“.hide()和.show()的执行速度会比直接改变css慢”。但由于未能找RobertDuffy问明原因,所以作者就自己去做了这个测试。下面的翻译并不是全文翻译,只节选了一些重点。
用作测试的是一个含有100个div的HTML页面,div带有 class和一些内容。为了排除掉寻找这些div所花费的时间,所以把选择器$('div')缓存起来了。用作测试的jQuery版本是1.4.2,所以测试结果也只是针对这个版本,在其他版本可能就不是这些结果了。
测试的jQuery方法分别是:
- .toggle()
- .show() 和 .hide()
- .css({'display':'none'}) 和 .css({'display':'block'})
- .addClass('hide') 和 .removeClass('hide')
- 改变<style>元素的一个属性
在所有浏览器中,这两个方法在隐藏DOM元素上相对来说比较慢。主要原因在于.hide()方法必须先保存元素的"display"属性,这样.show()才能把元素恢复到原来的状态。这里用到了.data()这个 jQuery方法,把信息保存在DOM元素上。为了达到这个目的,.hide()在每个元素上循环了两次,一次用来保存当前的"display"值,一次用来更新样式"display"为"none"。根据源代码上的注释,这样做是为了防止浏览器在每个循环上进行重新渲染(reflow)。.hide() 方法还会检查你是否传递了使用动画效果的参数,就算传入一个"0"也会让性能大打折扣。在第一次调用.hide()的时候性能最慢,在之后再调用则会变快。
在所有浏览器中,这两个方法在隐藏DOM元素上相对来说比较慢。主要原因在于.hide()方法必须先保存元素的"display"属性,这样.show()才能把元素恢复到原来的状态。这里用到了.data()这个 jQuery方法,把信息保存在DOM元素上。为了达到这个目的,.hide()在每个元素上循环了两次,一次用来保存当前的"display"值,一次用来更新样式"display"为"none"。根据源代码上的注释,这样做是为了防止浏览器在每个循环上进行重新渲染(reflow)。.hide() 方法还会检查你是否传递了使用动画效果的参数,就算传入一个"0"也会让性能大打折扣。在第一次调用.hide()的时候性能最慢,在之后再调用则会变快。
在所有浏览器中,这两个方法在隐藏DOM元素上相对来说比较慢。主要原因在于.hide()方法必须先保存元素的"display"属性,这样.show()才能把元素恢复到原来的状态。这里用到了.data()这个 jQuery方法,把信息保存在DOM元素上。为了达到这个目的,.hide()在每个元素上循环了两次,一次用来保存当前的"display"值,一次用来更新样式"display"为"none"。根据源代码上的注释,这样做是为了防止浏览器在每个循环上进行重新渲染(reflow)。.hide() 方法还会检查你是否传递了使用动画效果的参数,就算传入一个"0"也会让性能大打折扣。在第一次调用.hide()的时候性能最慢,在之后再调用则会变快。
Browser | hide/show |
FireFox 3.6 | 29ms / 10ms |
Safari 4.05 | 6ms / 1ms |
Opera 10.10 | 9ms / 1ms |
Chrome 5.0.3 | 5ms / 1ms |
IE 6.0 | 31ms / 16ms |
IE 7.0 | 15ms / 16ms |
这个方法是最慢的。它会检查选择器返回的每一个元素当前是否可见,如果可见的话就调用.hide()方法,不可见则调用.show()方法。不但如此,它不仅会检查你是否传递了一个boolean值进去阻止.hide()或者.show()的执行,还会检查看你是否传入了function来进行切换(toggle)而不是对可见性进行切换。看起来这个方法还有很大的改善空间,例如可以先一次过把隐藏的元素select出来,然后调用.show()方法,同时把其余的元素select出来调用.hide()方法。
这个方法是最慢的。它会检查选择器返回的每一个元素当前是否可见,如果可见的话就调用.hide()方法,不可见则调用.show()方法。不但如此,它不仅会检查你是否传递了一个boolean值进去阻止.hide()或者.show()的执行,还会检查看你是否传入了function来进行切换(toggle)而不是对可见性进行切换。看起来这个方法还有很大的改善空间,例如可以先一次过把隐藏的元素select出来,然后调用.show()方法,同时把其余的元素select出来调用.hide()方法。
这个方法是最慢的。它会检查选择器返回的每一个元素当前是否可见,如果可见的话就调用.hide()方法,不可见则调用.show()方法。不但如此,它不仅会检查你是否传递了一个boolean值进去阻止.hide()或者.show()的执行,还会检查看你是否传入了function来进行切换(toggle)而不是对可见性进行切换。看起来这个方法还有很大的改善空间,例如可以先一次过把隐藏的元素select出来,然后调用.show()方法,同时把其余的元素select出来调用.hide()方法。
Browser | hide/show |
FireFox 3.6 | 80ms / 59ms |
Safari 4.05 | 24ms / 30ms |
Opera 10.10 | 67ms / 201ms |
Chrome 5.0.3 | 55ms / 20ms |
IE 6.0 | 296ms / 78ms |
IE 7.0 | 328ms / 47ms |
这是两个很漂亮的隐藏/显示DOM元素方法。在Firefox上它的速度是.show() 和.hide()的两倍,而在Safari上则是三倍。不过在IE6,IE7,Chrome和Opera上,两种方法几乎没什么差别。值得一提的是,对于 100个DOM节点来说,两种方法在Firefox上相差18ms,在Safari相差4ms,速度的差异只会体现在大量节点选择的时候。不过增加和移除 class需要你花费更多的工作,因为你需要创建一个用于隐藏的class,然后还要时刻关注着这个class的优先级以保证DOM能隐藏。jQuery 增加和移除class是通过字符串操作的,所以我觉得随着元素上class数量的增加,这个方法会变慢,但是我还没对此进行测试过。
这是两个很漂亮的隐藏/显示DOM元素方法。在Firefox上它的速度是.show() 和.hide()的两倍,而在Safari上则是三倍。不过在IE6,IE7,Chrome和Opera上,两种方法几乎没什么差别。值得一提的是,对于 100个DOM节点来说,两种方法在Firefox上相差18ms,在Safari相差4ms,速度的差异只会体现在大量节点选择的时候。不过增加和移除 class需要你花费更多的工作,因为你需要创建一个用于隐藏的class,然后还要时刻关注着这个class的优先级以保证DOM能隐藏。jQuery 增加和移除class是通过字符串操作的,所以我觉得随着元素上class数量的增加,这个方法会变慢,但是我还没对此进行测试过。
这是两个很漂亮的隐藏/显示DOM元素方法。在Firefox上它的速度是.show() 和.hide()的两倍,而在Safari上则是三倍。不过在IE6,IE7,Chrome和Opera上,两种方法几乎没什么差别。值得一提的是,对于 100个DOM节点来说,两种方法在Firefox上相差18ms,在Safari相差4ms,速度的差异只会体现在大量节点选择的时候。不过增加和移除 class需要你花费更多的工作,因为你需要创建一个用于隐藏的class,然后还要时刻关注着这个class的优先级以保证DOM能隐藏。jQuery 增加和移除class是通过字符串操作的,所以我觉得随着元素上class数量的增加,这个方法会变慢,但是我还没对此进行测试过。
Browser | hide/show |
FireFox 3.6 | 11ms / 11ms |
Safari 4.05 | 2ms / 2ms |
Opera 10.10 | 6ms / 3ms |
Chrome 5.0.3 | 3ms / 1ms |
IE 6.0 | 47ms / 32ms |
IE 7.0 | 15ms / 16ms |
这两个方法也很漂亮。相对于.addClass() 和.removeClass(),IE6/7和Opera上的速度都得到了提升,而在其他浏览器上则能保持水准。当你知道要改变的元素的当前 display样式,或者没有通过inline的方式去改变元素的display样式时,这两个方法很好用。如果你通过inline的方式改变了 display样式,那么你需要确保在使得元素重新可见时display值要设置正确。如果你只是使用了元素的默认display值或者在css里设置 display值,那么你只需要用类似.css({'display':''})的方法移除样式,元素就会恢复到它在css上的样式或者默认display值。作为一个类库,jQuery不能假定元素的display不是通过inline方式设置的,所以它需要被人手的去确定。不过既然你知道你不会去inline的设置display,那么你就可以去避免这个造成缓慢的主要因素。
这两个方法也很漂亮。相对于.addClass()和.removeClass(),IE6/7和Opera上的速度都得到了提升,而在其他浏览器上则能保持水准。当你知道要改变的元素的当前display样式,或者没有通过inline的方式去改变元素的display样式时,这两个方法很好用。如果你通过inline的方式改变了display样式,那么你需要确保在使得元素重新可见时display值要设置正确。如果你只是使用了元素的默认 display值或者在css里设置display值,那么你只需要用类似.css({'display':''})的方法移除样式,元素就会恢复到它在 css上的样式或者默认display值。作为一个类库,jQuery不能假定元素的display不是通过inline方式设置的,所以它需要被人手的去确定。不过既然你知道你不会去inline的设置display,那么你就可以去避免这个造成缓慢的主要因素。
这两个方法也很漂亮。相对于.addClass()和.removeClass(),IE6/7和Opera上的速度都得到了提升,而在其他浏览器上则能保持水准。当你知道要改变的元素的当前display样式,或者没有通过inline的方式去改变元素的display样式时,这两个方法很好用。如果你通过inline的方式改变了display样式,那么你需要确保在使得元素重新可见时display值要设置正确。如果你只是使用了元素的默认 display值或者在css里设置display值,那么你只需要用类似.css({'display':''})的方法移除样式,元素就会恢复到它在 css上的样式或者默认display值。作为一个类库,jQuery不能假定元素的display不是通过inline方式设置的,所以它需要被人手的去确定。不过既然你知道你不会去inline的设置display,那么你就可以去避免这个造成缓慢的主要因素。
Browser | hide/show |
FireFox 3.6 | 14ms / 12ms |
Safari 4.05 | 2ms / 1ms |
Opera 10.10 | 2ms / 2ms |
Chrome 5.0.3 | 2ms / 1ms |
IE 6.0 | 16ms / 16ms |
IE 7.0 | 0ms / 0ms // 少于15ms会变成0ms |
纯粹为了好玩,我想:如果我们不在每个dom节点上花功夫,而是去捣鼓样式表会怎样呢?这样会提高速度吗?其实就日常使用来说,上面的测试用到的方法已经足够快了,但是如果页面上有10000个节点需要进行隐藏和显示呢?只是把它们全部选择出来就已经够慢了。如果我可以控制样式表,那么就可以完全避免这些时间花费了。不过我得告诉你,这个方法是有很大风险的。
风险在于控制样式表时的跨浏览器问题。首先,我尝试能不能通过jQuery插入一个带有class的"style"标签,但是却出现了跨浏览器问题。然后我尝试用javascript去创建stylesheet节点和class,但是实在有太多的API了,要搞清楚需要花不少的时间。最后,放弃了编程的方式,我在head区里写了一个带有class的style标签。通过编程的方式来创建stylesheet实在是太慢了,但是如果它一旦被创建好,那么给它一个ID和使用它的"disabled"属性就是轻而易举的事情了。
纯粹为了好玩,我想:如果我们不在每个dom节点上花功夫,而是去捣鼓样式表会怎样呢?这样会提高速度吗?其实就日常使用来说,上面的测试用到的方法已经足够快了,但是如果页面上有10000个节点需要进行隐藏和显示呢?只是把它们全部选择出来就已经够慢了。如果我可以控制样式表,那么就可以完全避免这些时间花费了。不过我得告诉你,这个方法是有很大风险的。
风险在于控制样式表时的跨浏览器问题。首先,我尝试能不能通过jQuery插入一个带有class的"style"标签,但是却出现了跨浏览器问题。然后我尝试用javascript去创建stylesheet节点和class,但是实在有太多的API了,要搞清楚需要花不少的时间。最后,放弃了编程的方式,我在head区里写了一个带有class的style标签。通过编程的方式来创建stylesheet实在是太慢了,但是如果它一旦被创建好,那么给它一个ID和使用它的"disabled"属性就是轻而易举的事情了。
纯粹为了好玩,我想:如果我们不在每个dom节点上花功夫,而是去捣鼓样式表会怎样呢?这样会提高速度吗?其实就日常使用来说,上面的测试用到的方法已经足够快了,但是如果页面上有10000个节点需要进行隐藏和显示呢?只是把它们全部选择出来就已经够慢了。如果我可以控制样式表,那么就可以完全避免这些时间花费了。不过我得告诉你,这个方法是有很大风险的。
风险在于控制样式表时的跨浏览器问题。首先,我尝试能不能通过jQuery插入一个带有class的"style"标签,但是却出现了跨浏览器问题。然后我尝试用javascript去创建stylesheet节点和class,但是实在有太多的API了,要搞清楚需要花不少的时间。最后,放弃了编程的方式,我在head区里写了一个带有class的style标签。通过编程的方式来创建stylesheet实在是太慢了,但是如果它一旦被创建好,那么给它一个ID和使用它的"disabled"属性就是轻而易举的事情了。
1 2 3 | <style id="special_hide">.special_hide { display: none; }</style> <!-- ... --> <div class="special_hide">Special hide DIV</div> |
1 | $('#special_hide').attr('disabled, 'true'); |
1 | $('#special_hide').attr('disabled', 'false'); |
简要回顾一下,下面是改变元素显示状态的方法,按照最快到最慢的次序排列:
- 禁用/启用样式表
- .css('display', ''), .css('display', 'none')
- .addClass(), .removeClass()
- .show(), .hide()
- .toggle()
.show() 和 .hide()
.toggle()
.addClass() 和 .removeClass()
.css({'display':'none'}) 和 .css({'display':'block'})
禁止样式表
然后在javascript里:
搞定!所有带有"special_hide"这个class的元素都显示出来了。要隐藏它们,你只需要……
现在它们全部都隐藏了。总的javascript耗时在所有浏览器上都是0-1ms。你的javascript只是用来改变一个属性。当然,浏览器还是需要花费时间去重新渲染页面的,但是实际上你已经避免了javascript的处理时间。如果你调用了.toggle(),.hide()或者.css()这几个方法,那么这个方法就会失效。因为那几个方法会通过内联方式设置css样式,这些样式有更高的优先级。要重新使这个方法生效,只需调用.css('display', '')把内联的样式移除掉。这个方法同样需要花费你更多的精力,因为那需要去定义class,同时把这些class赋给页面上需要进行显示/隐藏的元素,但是如果你所要处理的元素数量是极其庞大的话,那么这也许是值得的。
需要注意的是,在大多数的情况下,这些方法都足够的快了。当你要操作很大的jQuery集合时,那么.show() 和.hide()方法在IE下就会变得很慢了,这是你可能要用addClass() 或者 .removeClass()方法。禁用/启用样式表的方法只有在很极端的情况下才有必要用到
jquery的show/hide性能测试的更多相关文章
- jquery的show/hide/toggle详解
通过阅读源码我们发现show,hide,toggle调用了showHide和isHidden这2个方法,所以我们要搞明白原理必须先看一下这2个方法. jQuery.fn.extend({ ...... ...
- hidden,display,visibility ,jQuery中的hide()区别
hidden是html中的属性,规定元素是否可见 display是css中的样式,规定元素是否显示 visible 是css中的样式,规定元素是否可见 display:none ---不为被隐藏的对象 ...
- jQuery效果------隐藏hide()/显示show()
hide()和show() hide():隐藏文本. show():显示文本. 语法: $(selector).hide(speed,callback); $(selector).show(speed ...
- JQuery 支持 hide 和 show 事件的方法与分析
问题提出 JQuery不支持hide和show作为事件形式出现, 实际上这两个仅仅是JQuery对象的一个方法(fn): 有一类UI交互需求,根据一个DOM对象的或者显示对附属的DOM对象做相同操作 ...
- jQuery技巧大放送
1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...
- 【前端性能】必须要掌握的原生JS实现JQuery
很多时候,我们经常听见有人说jquery有多快多快.在这个各种类库满天飞的时候,不得不说的是,能有原生JS快吗? 是的,明显原生JS要更快,因为诸如JQuery这样的库必须要兼容各种浏览器和低版本和许 ...
- jQuery静态方法noConflict的使用和源码分析
所谓静态方法是jQuery本身得公共方法,并不需要通过实例化来调用,一般也称为工具方法,下面先来列绝下jQuery.noConflict方法的用法: noConflict() 方法让渡变量 $ 的 j ...
- JQuery常用方法一览
$(”p”).addClass(css中定义的样式类型); 给某个元素添加样式 $(”img”).attr({src:”test.jpg”,alt:”test Image”}); 给某个元素添加属性/ ...
- jquery实现前台倒计时。应用下单24小时后自动取消该订单
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
随机推荐
- Generate List and Table via ng-repeat
<div ng-app ng-controller='StudentListController'> <ul> <li ng-repeat='student in stu ...
- 在Silverlight宿主html页面添加按钮无法显示
在建silverlight应用程序时宿主html中嵌入的silverlight时出现的问题: 预想效果: 实际效果: silverlight填满整个page的所以无法显示html中其他的控件 解决办法 ...
- 线程操作API
线程操作API 1.currentThread 2.getId() .getName().getPriority().getStart.isAlive().isDaemon().isInterrupt ...
- Java入门到精通——基础篇之面向对象
一.概述. Java属于面向对象的一种语言,因为Java是面向对象的语言所以这个语言的诞生需要有五个基本特性: 1)万物皆为对象. 2)程序是对象的集合. 3)每个对象都有自己的由其他对象所构成的存储 ...
- QPBOC扩展应用交易流程
1 Q扩展部分数据 增加3个DGI,分别为:A001,8020,9020 9103中增加DF60(9F38中),DF61 增加DF62,DF63 1.1 A001扩展应用配置 DGI 长度 值(示例 ...
- WebApp JS 打开 app
产品需求:分享出去的链接比如到微信朋友圈,微博的H5页面,添加一个按钮 open App 用来打开并启动自己公司的APP (如果当前手机已经安装自己公司的APP) 废话少说直接上代码: <inp ...
- hdu 2094 产生冠军
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2094 产生冠军 Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比 ...
- hdu 1250 Hat's Fibonacci
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1250 Hat's Fibonacci Description A Fibonacci sequence ...
- 安装Ubuntu 15.10后要做的事
Ubuntu 15.10发布了,带来了很多新特性,同样也依然带着很多不习惯的东西,所以装完系统后还要进行一系列的优化. 1.删除libreoffice libreoffice虽然是开源的,但是Java ...
- WinForm GDI+自定义控件总结(一)
前言 由于项目的原因好久没写博客了,也正是项目的原因开始系统的学习WinForm,从而接触到自定义控件的开发.自定义控件的开发有一定的难度,对开发者要求比较高,需要了解Windows运行的机制,熟悉w ...