-2

I've got a div with a lot of stuff in it. For one, it's got a Chart in it (from amCharts), and several sliders from noUiSlider. It's also composed of a lot of AngularJS functionality as well. I try to hide the page by doing $('#container').addClass('hidden') where hidden has the rule display:none !important.

It works, but takes maybe 500ms to perform. The same goes if I do height: 0 !important instead of display: none !important. I'm basically trying to mimic a page change when the user clicks on a different menu item, so I'd like it to at least not flicker like it does now. I'm wondering if any css experts here know of a better way to quickly hide a big, complex div.

By the way I'm using Chrome with an i3 2nd generation. Not the best processor, but enough people use this quality machine that I'd like to get it smoother.

Note: I have no JSFiddle because the page is incredibly complicated and requires a MySQL backend.

halfer
  • 19,824
  • 17
  • 99
  • 186
user3413723
  • 11,147
  • 6
  • 55
  • 64
  • can you provide a jsFiddle sample to recreate the scenario. – Bala Mar 20 '15 at 04:46
  • 1
    Try fading the div away? – Nevin Madhukar K Mar 20 '15 at 04:47
  • I made a JSBin of just the AmChart, but that seemed to disappear instantly. To recreate the entire page would not be easy, and further, I don't want to release the code online. I was just wondering if anyone knows a better way off the top of their head. – user3413723 Mar 20 '15 at 04:48
  • Fading is about the same. The crazy thing is that it stutters on hiding, but works instantly to show the div again. – user3413723 Mar 20 '15 at 04:50
  • 500ms is very slow, but then again, if the page is highly complex, you are asking the browser to completely recompute the layout, so it is not out of the question, and no, if you want something not to be displayed, there is no option other than to tell it `display: none`. –  Mar 20 '15 at 04:52
  • the possible delay of 500ms is probably due to the code $('#container').addClass('hidden'); is written after a few javascript calculations. My best bet would be to make it the first line of code after the click event is triggered. – Bala Mar 20 '15 at 04:53
  • This sounds awfully similar to http://stackoverflow.com/questions/28971440/chrome-v41-performance-issue-with-display-none-on-lots-of-nodes except in this case it's setting `display: none` on a single element with lots of descendants, as opposed to setting it on lots of individual elements. – BoltClock Mar 20 '15 at 05:08

4 Answers4

2

According to this article on show/hide performance it appears that changing the CSS directly from display: none and display: block is the fastest way from performance testing among browsers. Although a note that for subsequent hide/shows using .hide() and .show() for jQuery does get faster:

1st .css({'display':'none'}) & .css({'display':'block'});

Browser         hide/show
FF3.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 

2d .show() & .hide()

Browser         hide/show
FF3.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 

3rd .addClass() & .removeClass()

Browser      hide/show
FF3.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

I've also ran my own test case against .css({'display':'none'}) vs .hide() and it seems that .css({'display':'none'}) is faster:

Spencer Wieczorek
  • 21,229
  • 7
  • 44
  • 54
1

Instead of adding class you can do this way

$('#container').hide();
stanze
  • 2,456
  • 10
  • 13
  • 1
    And this would be faster because...?? Do you know what it actually does? –  Mar 20 '15 at 04:50
  • when .hide() is called the value of the display property is saved in jQuery's data cache. – stanze Mar 20 '15 at 04:51
  • How is that any better? It's still doing `display: none` Proof https://github.com/jquery/jquery/blob/9b03f6df88a8d9dbda3f7893cdd84e3a3c70da17/src/css.js#L206 – Miguel Mota Mar 20 '15 at 04:52
  • I think this is a comment, not an answer. –  Mar 20 '15 at 04:53
  • Well, I didn't think it would work, but it does! I know that `hide()` internally calls `display:none`, so that made me think that this would be no different. The difference here, though, is that I am changing style on the element directly instead of indirectly by adding a new class. I guess when I add a class, Chrome tries to re-render the whole div first which causes the slowdown. – user3413723 Mar 20 '15 at 04:54
1

Strangely enough, adding the class hidden takes far longer then simply adding the attribute display:none in Chrome. Calling jQuery's hide() actually adds the style to the element, instead of adding the new class. Even though both accomplish basically the same thing, one strangely takes drastically longer than the other. I guess Chrome tries to rerender the whole thing if I add the class, and then hide it. But if I just add display:none, it realizes that I just want to hide it, and does not rerender.

user3413723
  • 11,147
  • 6
  • 55
  • 64
0

For the css class try

visibility: hidden;

display will remove the element entirely from the DOM. visibility will hide it, so all that energy for rendering is conserved.

The problem with this is that the visibility will hold the place in the dom. You will need to find a way to fill the gap, which may or not be what you are looking to do.

In regards to performance, this is a jsPerf. This only demonstrates a marginal difference between the two on a simple div. Here is another SO question that digs into the details. Visibility leaves the box elements in the rendering tree, so that less work is needed to add it back in. For a complex element tree, I would think that you would see a more dramatic difference as to what happened in the jsPerf.

Community
  • 1
  • 1
yxre
  • 3,576
  • 21
  • 20
  • `" all that energy for rendering is conserved"`, can you provide performance tests to prove that? – Miguel Mota Mar 20 '15 at 04:56
  • Do you know what 'visibility' does? The element will continue to occupy physical space on the page, just not be displayed. It's unlikely that's what the OP wants. BTW, I think you're confused about the difference between "DOM" and "rendered page". `display` does **not** 'remove the element from the DOM". It does not render it, which is an entirely different thing. –  Mar 20 '15 at 05:06
  • Its a suggestion for the OP to try. I did mention the distinction in the behavior in my original post. As for the difference between DOM and rendered page, I was implying the visible DOM, but rendered page is much more clear. – yxre Mar 20 '15 at 05:11