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 ...
随机推荐
- jqGrid(2)
jqGrid使用方法: 原文地址:http://blog.csdn.net/y0ungroc/article/details/12008879 1. 下载文件 1. 下载jqGrid的软件包, ...
- [terry笔记]Flashback
flashback 闪回,主要功能有两个:闪回查询(flashback query).闪回恢复(flashback table/database) 开启闪回flashback功能(归档下才可开启数据库 ...
- SQL基础篇---基本概念解析
1.数据库database:保存表和其他相关SQL结构容器(一般是一个文件或者一组文件) 2.SQL (Structared Query Language):是一种专门用来与数据库沟通的语言,是一种结 ...
- 公钥私钥 ssl/tsl的概念
一,公钥私钥1,公钥和私钥成对出现2,公开的密钥叫公钥,只有自己知道的叫私钥3,用公钥加密的数据只有对应的私钥可以解密4,用私钥加密的数据只有对应的公钥可以解密5,如果可以用公钥解密,则必然是对应的私 ...
- Go语言工程结构
Go是一门推崇软件工程理念的编程语言. Go的代码必须放在GOPATH目录下,它应该包含三个子目录: src:用于以代码包的形式组织并保存Go源码文件.应该分为三类:库源码文件.命令源码文件.测试源码 ...
- [译]rabbitmq 2.5 Where’s my message? Durability and you
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. There’s a dirty secret about creating queues and exchanges in ...
- ASP.NET分页
[代码][C#]代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...
- ExtJS MVC学习手记 1
开发环境: ExtJS4.2 eclipse indigo 开发目标 搭建项目框架,创建viewport 开发步骤说明 这次主要使用extjs4的mvc模式创建viewport.籍此初步了解mvc模 ...
- 62.在cdc文件上某些例化模块看不到的原因
比如在顶层文件中,例化了几个模块,综合后打开cdc文件,会在structure/net中少几个例化模块,即看不到,但在顶层文件中还是存在的,只是ISE软件综合的问题而已,原因是在顶层或子模块中,有些应 ...
- arm-elf-gcc汇编代码个人理解
arm-elf-gcc汇编代码个人理解 有关arm-elf-gcc的安装使用问题请参照本人博客的另一篇文章http://www.cnblogs.com/wsine/p/4664503.html 由于各 ...