Jquery hide() and show() runs too slow in google chrome
I have a web application that doesn't run correctly in chrome. Works perfectly in Firefox. I have a page with a large numbered of list items, 316 to be exact. Each list item contains a large amount of HTML. My problem is when I want to hide or show these list items.
I have a test page on jsFiddle to show the problem I'm having. I stripped down the HTML page to one unordered list to hold all 316 list items. I have two buttons that simply call jQuery hide or show when clicked. Again this runs fast in Firefox, Opera, even IE, pretty well in Safari but in Google Chrome it can take over 30 seconds which brings up the dialog window 开发者_JS百科asking if you want to kill the page because a script is running to long.
Here is the link to jsFiddle
http://jsfiddle.net/oumichaelm/UZCZc/3/embedded/result/
thanks for any input. jmm
Looks like this has nothing to do with jQuery and just is a problem with Chrome hiding an parent element that has a HUGE number of children elements.
This just uses basic javascript to hide the element on document ready:
document.getElementById('sortable-lines').style.display="none";
And it still takes forever after the document is ready.
http://jsfiddle.net/petersendidit/UZCZc/10/embedded/result/
Opened a Chrome bug for this: http://code.google.com/p/chromium/issues/detail?id=71305
When hiding, removing the element from the DOM is faster than using hide()
.
var sortableLines = $('#sortable-lines');
$('#hide').click(function() {
$('#timer').text("Hiding");
sortableLines.remove();
});
It is still slow when you append()
it back to the DOM.
A possible workaround is to show the first 10 or so items when the show button is clicked, and then setInterval
to progressively show them.
Edit: Found another hack:
You have to set the container to overflow: hidden
:
#linecontainer { overflow: hidden; }
When hiding, move that element up to far top, by setting margin-top
to a big negative number.
$('#hide').click(function() {
$('#timer').text("Hiding");
sortableLines.css('margin-top', '-1000000px');
});
When showing, reset its margin-top
.
$('#show').click(function() {
$('#timer').text("Showing");
sortableLines.css('margin-top', '0');
});
And it shows and hides instantly.
Thanks for the answer above, it works great and speeds up the process.
It doesn't however always work - Works nice when the elements I need are at the top of the list. However, it doesn't show them all if I pick something from the middle of the list.
I believe I know why it misbehaves.
When the value of a long list of elements is set to hide/show the hidden elements are removed from the flow and placed on the bottom of the page in the order they were removed.
This makes removing the elements remarkably fast.
However, trying to make them visible again is a pain on the rendering as chrome has to remember the order in which these items belonged in and seemingly to recompute the values associated.
Other than most other browsers the spot for the component isn't lost so no time is wasted in this unnecessary sorting. The above answer works remarkably well as this avoids Chrome's disordering problem.
精彩评论