In jQuery, using the :visible selector can be dangerous

14 September 2010   0 comments   Javascript

Mind That Age!

This blog post is 7 years old! Most likely, it's content is outdated. Especially if it's technical.

Powered by Fusion×

In jQuery, using the :visible selector can be dangerous And by "dangerous" I mean super slow to the point of making your browser shake of over exhaustion.

I have a big fat table where on the left hand side of each row there's a little toggle to open up an initially hidden sub-table. And there are toggles for those sub-tables to open up further sub-tables. It might sound complicated but it works great. The code for each toggle looks something like this:

$('a.toggle-order-on').click(function() {
   var tbody_parent = $(this).parents('tbody');

   $('tr.printdisplay:hidden', tbody_parent).show();
   $('tr.outdoor-marketing:hidden', tbody_parent).show();
   $('', tbody_parent).show();

   // expand the little table too
   $('a.toggle-printdisplay-on', tbody_parent).click();

   var td_parent = $(this).parents('td');
   $('a.toggle-order-off:hidden', td_parent).show();

   return false;

Note the heavy use of the super useful :hidden selector which is basically a reversing wrapper on the :visisble selector

What I then needed was a way to open up every single row in the whole table with one click. Here was the code I wrote:


See? Makes sense does it?

Problem with this was that when the table was big sometimes clicking this would make my otherwise fast browser (Chrome or Firefox) stutter and sometimes stall or at worst the alert pop-up about "a script is slowing this page down" would appear.

So I started the Firebug Profiler and clicked a couple of times and collected some numbers. On average it took 3-4.5 seconds!! and about 20,000-35,000 calls to complete the full expansion. Yikes! About 90% of the time spent by jQuery was on the visisble() function.

Solution: Instead of using the click trigger I simply just called the .show() effect on all things manually without using any :visible or :hidden operators. Here's the new code:




This time, with the profile again, I it took on average 0.2-0.3 seconds and required about 2000-4000 calls. HUGE difference.

So, remember that next time. Don't just re-use working code en mass if it's using a much of :visible or :hidden selectors somewhere in there.


Thank you for posting a comment

Your email will never ever be published

Related posts

wkhtmltopdf and font size shrinkage 10 September 2010
Local Django development with Nginx 11 October 2010
Some tips on learning React 04 August 2015
mincss version 0.8 is much much faster 27 February 2013
Difference between $.data('foo') and $.attr('data-foo') in jQuery 10 June 2012
QUnit testing my jQuery Mobile site in full swing 17 March 2011
Why I gave up on JQuery UI's autocomplete 20 October 2010
To $('#foo p') or to $('p', $('#foo')) 24 February 2009
Lesson learnt with creating DOM element with jQuery 04 April 2008
Why Django and Grok matters 02 February 2008
jQuery and Highslide JS 08 January 2008
JetBlue a good and bad website 22 February 2007