Performance differences between visibility:hidden and display:none
Solution 1
I'm not aware of any performance difference between display:none
and visibility:hidden
- even if there is, for as little as 10 elements it will be completely negligible. Your main concern should be, as you say, whether you want the elements to remain within the document flow, in which case visibility
is a better option as it maintains the box model of the element.
Solution 2
display:none;
elements are not in the render tree all, so they will perform better at face value.
I doubt you will have any real visible performance problems from this though. If you need opacity: 0
or visibility: hidden
because of their functionality, then just use them. If you don't need the functionality, then use display: none;
Solution 3
If you are toggling between visible and invisible states via javascript then visibility:hidden should be the better performer. Seeing as it always takes up the same amount of space in both visible and hidden states it won't cause a reflow of the elements below it every time you make it appear of disappear. For display:none you are removing it from the flow of the document and then when you set it to display:block you are rerendering it and pushing everything below that element down, essentially laying all that stuff out again.
But if you are doing something like toggling visible states on button presses then you really should be using what suits your needs rather than what performs better, as the performance differences are negligible in such cases. When you are animating with the dom at around 20 times per second THEN you can worry about the performance of visibility:hidden vs display:none.
Solution 4
visibility: hidden
does not cause a re-flow on the document, while display: none
does.
display: none
: The HTML engine will completely ignore the element and its children. The engine will not ignore elements marked with visibility: hidden
, it will do all the calculations to the element and its children, the exception is that the element will not be rendered to the viewport.
If the values for position and dimensions properties are needed then visibility: hidden
have to be used and you have to handle the white space in the viewport, usually by wrapping that element inside another one with 0 width and height and 'overflow: hidden'.
display:none
will remove the element from the document's normal flow and set the values for position/height/width to 0 on the element and its children. When the elements display
property is changed to other value than none
, it triggers a complete document re-flow, which can be a problem for big documents - and sometimes not-so-big documents being rendered on hardware with limited capabilities.
display: none
is the natural and logical solution to use when hiding elements on the viewport, visibility: hidden
should be used as a fallback, where/when needed.
EDIT:
As pointed by @Juan, display: none
is the choice to go when what you need is to add many elements to the DOM tree. visibility: hidden
will trigger a re-flow for each element added to the tree, while display: none
will not.
Solution 5
Well, the main performance difference between display: block
and visibility: hidden
is that if you have a list of, say, 100000 elements, the visibility: hidden
won't save you from DOM hanging because it doesn't remove elements from DOM.
visibility: hidden
acts like opacity: 0
+ pointer-events: none
. display: none
acts like Element.remove()
.
Live example: https://jsfiddle.net/u2dou58r/10/
Wolfgang Adamec
Updated on December 15, 2020Comments
-
Wolfgang Adamec over 3 years
I want to simplify things in my jQuery Backbone.js web application. One such simplification is the behavior of my menu and dialog widgets.
Previously I created the div boxes of my menus at start and hid them using
display: none; opacity:0;
. When I needed a menu, I changed its style todisplay:block
then used the jQuery ui position utility to position the div box (since elements withdisplay:none
cannot be positioned) and when it was done, finally changed its style toopacity:1
.Now I want to just hide them with
visibility:hidden
, and when I need one, I use the position utility and then change the style tovisibility:visible
. When I begin using this new approach, I will have around 10 div boxes throughout the web application session that are hidden but occupy space, in contrast to the previous div boxes hidden withdisplay:none
.What are the implications of my new approach? Does it effect browser performance in any regard?
-
chrisfrancis27 over 11 years+1 - very interesting! Do you know which browsers have this render tree optimisation?
-
Esailija over 11 years@ChrisFrancis I want to say all but you can never know about IE :D
-
Esailija over 11 yearsJust because an element is in DOM hierarchy doesn't mean anything in terms of performance. It depends on how costly it is to render that element and its children on the screen, which can vary arbitrarily.
-
Marcelo De Zen over 11 yearsEven IE ignores the element if it has "display: none".
-
Dan Abramov almost 10 yearsAlthough it may perform better the first time, if you're toggling
display
fast, you're asking for trouble. Check out the other answers. -
Stephen M. Harris over 9 yearsI'd upvote this if you provided sources. I know that
display:none
causes a reflow whereasvisibility:hidden
does not ... so intuitively I think you are dead-on. But good answers on SO link to official documentation or deeper explanations; I don't have enough background on this subject to +1 this without sources. -
Francisc0 about 9 yearsthis article by Nicole Sullivan talks about it. She's generally considered a CSS expert and helped to build CSSLint. Don't know if this qualifies as a good source but I certainly trust her opinion stubbornella.org/content/2009/03/27/…
-
Juan Lanus about 9 yearsThis is the real issue with display:none vs. visibility:hidden. If you are adding a lot of elements to a DOM, and you add them hidden, then you'll provoke a reflow for each one. On the other hand, you can add as many elements as you want with display:none and show them all at once provoking a single reflow. The performance taxing action is the the reflow.
-
FlavorScape almost 8 yearsin cases where you have hundreds of elements, such as a tiled map or game, I always remove display attributes in reverse-dom order to prevent reflows on the container!
-
Thor Lancaster over 4 yearsFor one of my pages with 3D CSS effects and several thousand elements in the DOM, toggling "display" on a large container element caused a lag of almost 500ms on slower mobile devices. Changing the CSS to instead toggle "visibility" eliminated the lag entirely.
-
Ayyappa Gollu over 4 years@andywhyisit from this resource it says that changine display to None doesn't cause reflow .. but changing visibility to hidden cause 1x reflow in browsers. developers.google.com/speed/docs/insights/browser-reflow for me your answer seems correct. but resoursce provided aboove contradicts it. so which one is right ?
-
gaurav5430 over 2 yearsboth of them are in the DOM tree, but display:none wouldn't be in the render tree
-
gaurav5430 over 2 yearswhy would display:none perform better at face value? it is not in the render tree, but as soon as you toggle it to display: block or other, it will become a part of the render tree and lead to re layout, while visibility change (theoretically) should not lead to trigger layout
-
gaurav5430 over 2 years@juanlanus are you suggesting that adding a lot of elements with visibility hidden and changing the visibility to visible for each one of them would provoke a reflow of the document / parent element? OR are you suggesting that each of these elements would reflow every time there is a reflow triggered on the doc due to some reason, as they are part of the render tree?
-
gaurav5430 over 2 yearsis that because visibility: hidden elements are still aprt of the layout step bit not display:none
-
Marcelo De Zen over 2 years@gaurav5430 a reflow is triggered when a new element is inserted into the DOM. However, if the parent element has display:none, the reflow is not triggered when a new element is added. Visibility:hidden will still trigger a reflow.
-
gaurav5430 over 2 yearswhy though, the element is already in the DOM / render tree, we only toggle the visibility from none to visible
-
Limbo over 2 years@gaurav5430 well, technically, yes. But it's not quite correct to say that
display: none
elements are not part of the layout, because they can be still reached through JS DOM methods (likequerySelector
). Also, they will still affectnth-child
CSS pseudo-selectors