2009-04-13 43 views
5

因为我使用jQuery 1.3+除了一个定时测试正在使用它。另一个是我在2000年发现的纯javascript。我停止了这条路线,因为它需要大约150秒来运行测试。我已经阅读了很多与选择单个元素相关的jQuery优化网页。 '#id'是使用它的最好情况,但现在我有检查一个列中的所有复选框在一个相当大的表中有多个复选框列的问题。什么是选择大量复选框并取消/选择它们的最快方法?

我所做的是设置一个页面,创建两个复选框列的20,000表行。目标是检查第二栏,看看花了多长时间,然后取消选中它们,看看花了多长时间。显然我们想要最短的时间。我只使用IE6和7,在我的情况下,我的所有用户都会这样做。

你说20000行?这也是我所说的,但这是生产(我手中没有),现在改变已经太迟了。我只是想在时钟上留下1秒钟的雹子。另外,我知道input.chkbox不是最快的选择器(对于IE7)! :)

问题是,有没有更好的方法来做这个jQuery或以其他方式吗?我希望它能在我的机器上运行不到半秒钟。

所以你不必重新输入所有我已经在这里做的废话是测试的东西,我想出了:

更新上午4/14,包括进一步的试运行时间:

<form id="form1" runat="server"> 
<div>   
     <a href="#" id="one">input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="two">#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="three">#myTable tr.myRow input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="four">tr.myRow input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="five">input[id^='chkbox']</a><br /> 
     <a href="#" id="six">.chkbox</a><br /> 
     <a href="#" id="seven">input.chkbox</a><br /> 
     <a href="#" id="eight">#myTable input.chkbox</a><br /> 

     <a href="#" id="nine">"input.chkbox", "tr"</a><br /> 
     <a href="#" id="nine1">"input.chkbox", "tr.myRow"</a><br /> 
     <a href="#" id="nine2">"input.chkbox", "#form1"</a><br /> 
     <a href="#" id="nine3">"input.chkbox", "#myTable"</a><br /> 

     <a href="#" id="ten">input[name=chkbox]</a><br /> 
     <a href="#" id="ten1">"input[name=chkbox]", "tr.myRow"</a><br /> 
     <a href="#" id="ten2">"input[name=chkbox]", "#form1"</a><br /> 
     <a href="#" id="ten3">"input[name=chkbox]", "#myTable"</a><br /> 

     <a href="#" id="ten4">"input[name=chkbox]", $("#form1")</a><br /> 
     <a href="#" id="ten5">"input[name=chkbox]", $("#myTable")</a><br /> 

     <a href="#" id="eleven">input[name='chkbox']:checkbox</a><br /> 
     <a href="#" id="twelve">:checkbox</a><br /> 
     <a href="#" id="twelve1">input:checkbox</a><br /> 
     <a href="#" id="thirteen">input[type=checkbox]</a><br /> 

     <div> 
      <input type="text" id="goBox" /> <button id="go">Go!</button> 
      <div id="goBoxTook"></div> 
     </div> 

     <table id="myTable"> 
      <tr id="headerRow"><th>Row #</th><th>Checkboxes o' fun!</th><th>Don't check these!</th></tr> 
      <% for(int i = 0; i < 20000;i++) { %> 
      <tr id="row<%= i %>" class="myRow"> 
       <td><%= i %> Row</td> 
       <td> 
        <input type="checkbox" id="chkbox<%= i %>" name="chkbox" class="chkbox" /> 
       </td> 
       <td> 
        <input type="checkbox" id="otherBox<%= i %>" name="otherBox" class="otherBox" /> 
       </td> 
      </tr> 
      <% } %> 
     </table> 
</div> 
     <script type="text/javascript" src="<%= ResolveUrl("~/") %>Javascript/jquery.1.3.1.min.js"></script> 
     <script type="text/javascript"> 

      $(function() {     
       function run(selectorText, el) {      
        var start = new Date();      
        $(selectorText).attr("checked", true);        
        var end = new Date(); 
        var timeElapsed = end-start; 
        $(el).after("<br />Checking Took " + timeElapsed + "ms"); 

        start = new Date();      
        $(selectorText).attr("checked", false);        
        end = new Date(); 
        timeElapsed = end-start; 
        $(el).after("<br />Unchecking Took " + timeElapsed + "ms"); 
       }  

       function runWithContext(selectorText, context, el) {      
        var start = new Date();      
        $(selectorText, context).attr("checked", true);        
        var end = new Date(); 
        var timeElapsed = end-start; 
        $(el).after("<br />Checking Took " + timeElapsed + "ms"); 

        start = new Date();      
        $(selectorText, context).attr("checked", false);         
        end = new Date(); 
        timeElapsed = end-start; 
        $(el).after("<br />Unchecking Took " + timeElapsed + "ms"); 
       } 

       $("#one").click(function() {       
        run("input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#two").click(function() { 
        run("#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#three").click(function() { 
        run("#myTable tr.myRow input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#four").click(function() { 
        run("tr.myRow input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#five").click(function() { 
        run("input[id^='chkbox']", this); 
       }); 

       $("#six").click(function() { 
        run(".chkbox", this); 
       }); 

       $("#seven").click(function() { 
        run("input.chkbox", this); 
       }); 

       $("#eight").click(function() { 
        run("#myTable input.chkbox", this); 
       }); 

       $("#nine").click(function() { 
        runWithContext("input.chkbox", "tr", this); 
       }); 


       $("#nine1").click(function() { 
        runWithContext("input.chkbox", "tr.myRow", this); 
       }); 
       $("#nine2").click(function() { 
        runWithContext("input.chkbox", "#form1", this); 
       }); 
       $("#nine3").click(function() { 
        runWithContext("input.chkbox", "#myTable", this); 
       }); 

       $("#ten").click(function() { 
        run("input[name=chkbox]", this); 
       });     

       $("#ten1").click(function() { 
        runWithContext("input[name=chkbox]", "tr.myRow", this); 
       }); 

       $("#ten2").click(function() { 
        runWithContext("input[name=chkbox]", "#form1", this); 
       }); 

       $("#ten3").click(function() { 
        runWithContext("input[name=chkbox]", "#myTable", this); 
       }); 

       $("#ten4").click(function() { 
        runWithContext("input[name=chkbox]", $("#form1"), this); 
       }); 

       $("#ten5").click(function() { 
        runWithContext("input[name=chkbox]", $("#myTable"), this); 
       }); 

       $("#eleven").click(function() { 
        run("input[name='chkbox']:checkbox", this); 
       }); 

       $("#twelve").click(function() { 
        run(":checkbox", this); 
       }); 

       $("#twelve1").click(function() { 
        run("input:checkbox", this); 
       }); 

       $("#thirteen").click(function() { 
        run("input[type=checkbox]", this); 
       }); 

       $('#go').click(function() { 
        run($('#goBox').val(), this); 
       }); 
      }); 
     </script> 
</form> 
+0

我并不意味着无益,但在一页中的20k行只是坏的设计。你应该解决这个问题。 :) – 2009-04-13 23:24:19

+0

呃...没有开玩笑。 :)我没有做到!现在没有足够的时间为此版本修复它。这将是下一个版本首先要做的事情。尽管如此,这个项目带来了许多“有趣”的挑战。 – rball 2009-04-13 23:31:07

回答

8

输入[名称= chkbox]是IE7下我机器上最快的jQuery选择器。

Unchecking Took 2453ms 
Checking Took 2438ms 
Unchecking Took 2438ms 
Checking Took 2437ms 
Unchecking Took 2453ms 
Checking Took 2438ms 

input.chkbox和...

Unchecking Took 2813ms 
Checking Took 2797ms 
Unchecking Took 2797ms 
Checking Took 2797ms 
Unchecking Took 2813ms 
Checking Took 2797ms 

输入:checkbox.chkbox似乎很依赖

Unchecking Took 2797ms 
Checking Took 2797ms 
Unchecking Took 2813ms 
Checking Took 2781ms 

.chkbox的两倍,几乎需要为input.chkbox

Unchecking Took 4031ms 
Checking Took 4062ms 
Unchecking Took 4031ms 
Checking Took 4062ms 

for循环中的JavaScript是迄今为止最糟糕的进来:

Checking Took 149797ms 

150秒!它也锁定浏览器。这让我对jQuery印象深刻。我真的没想到它会那么慢。可能是因为我正在通过每个单独的元素,然后它必须找到...

这相当有趣,我还有:

输入[ID^= 'chkbox']

Unchecking Took 3031ms 
Checking Took 3016ms 

的时间比:

输入[ID^='chkbox'] [type ='checkbox']

Unchecking Took 3375ms 
Checking Took 3344ms 

我以为我发布了更多的过滤器会更快。不!

指定更路径的复选框使得方式较慢:

#myTable TR [ID^= '行']输入[ID^= 'chkbox'] [式= '复选框']

Checking Took 10422ms 

它甚至没有运行第二个取消选中,因为它问我是否想继续在我的电脑上运行脚本。疯! :P

更新上午4/14:

有人提出了设置背景:其实我做了几那些使我很吃惊的和反对的正是很多人都在网络上说在IE7上,这些速度较慢!下面是我用几个不同的上下文中的指定用更快的选择器的上方配对拿到了时间:

“input.chkbox”, “TR”

Checking Took 8546ms 

“input.chkbox”,“TR .myRow”

Checking Took 8875ms 

“input.chkbox”, “#form1的”

Unchecking Took 3032ms 
Checking Took 3000ms 

“input.chkbox”, “#myTable”

Unchecking Took 2906ms 
Checking Took 2875ms 

当前胜者(静止):输入[名称= chkbox]

Unchecking Took 2469ms 
Checking Took 2453ms 

“输入[名= chkbox]“,”tr。myRow”

Checking Took 9547ms 

“输入[名称= chkbox]”, “#form1的”

Unchecking Took 3140ms 
Checking Took 3141ms 

“输入[名称= chkbox]”, “#myTable”

Unchecking Took 2985ms 
Checking Took 2969ms 

更新2上午4/14

以为我注意到与http://beardscratchers.com/journal/jquery-its-all-about-context的语法差异后,可能会有更好的一个。看起来这些与不一样,他们给出的时间稍微好一些,但仍然没有击败非竞争选择器 - darn。

“输入[名称= chkbox]”,$( “#form1中”)

Unchecking Took 3078ms 
Checking Took 3000ms 
Unchecking Took 3078ms 
Checking Took 3016ms 

“输入[名称= chkbox]”,$( “#myTable的”)

Unchecking Took 2938ms 
Checking Took 2906ms 
Unchecking Took 2938ms 
Checking Took 2921ms 

更新3晨4/14

拉斯想让我尝试这些了,他们去/选择所有的微博XES但同样很有意思:

:复选框

Unchecking Took 8328ms 
Checking Took 6250ms 

输入:复选框

Unchecking Took 5016ms 
Checking Took 5000ms 

- >最快?!?! 输入[类型=复选框]

Unchecking Took 4969ms 
Checking Took 4938ms 

第三那里是最快的,这一事实就是这么违背了我本来以为挺有意思的。为什么不(对于IE7来说):复选框只是使用type =复选框来获得更快的时间?这些分数非常接近,但检查时间缩短了62ms。另外,为什么前两个不同呢?除了可以带有复选框的输入外,是否还有其他元素?

5

我还没有测试过这个,但是你可以尝试在页面加载时创建一个数组[]的复选框引用,然后简单地迭代每次你想做出改变?

您会在页面加载时支付性能成本,但其可能是比每次步行DOM都快。嘿,至少你会在用户'停机时间'中执行繁重的工作(人们需要多长时间才能找到并单击取消选择/选择选项)。

+0

或者我想知道是否可以在第一次(或在加载时)将它们“缓存”到数组中,然后当它们再次打开时它会更快。很酷的想法,我会放手一搏。 – rball 2009-04-13 23:18:44

+0

让我知道你如何得到! – Codebrain 2009-04-13 23:19:36

+0

会做,但可能是明天,因为工作日快要结束了。 – rball 2009-04-13 23:20:58

2

我唯一的建议可能不会工作。切换浏览器。但我只有一家公司实际上同意这一点。我们将公司切换到FireFox,并且特定用户转移到Google Chrome。 IE浏览器对JavaScript来说太慢了。

此外,您可以尝试预先缓存jQuery查询列表。

如果一切都失败了,用心理学解决。这意味着让用户知道某些事情需要很长时间。在功能执行时放置一个“Please wait”div。这样用户就知道浏览器不仅仅是锁定了,而且他们知道什么时候可以重新开始工作。通过这样做,我已经解决了很多慢页面。

1

您是否尝试过使用context来查看jQuery选择器是否可以提高性能?据推测,这些控件将位于ASP.NET表单中,并且可能是另一个独特的可识别元素?

例如,如果你有

$("input[id^='chkbox']") 

上下文与

$("input[id^='chkbox']", "#myFormID") 

Here's a BeardScratchers article尝试

编辑:

按照你的更新,它似乎像2.45- 6秒根据你的情况,这可能是你能达到的最快速度。

只是为了完整性,您是否尝试过以下选择器?

$(':checkbox') 
$('input[type=checkbox]') 
相关问题