Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does 'display: none;' improve or worsen performance?

Tags:

I have a page with a lot of vertical scrolling and thousands of DOM elements. For improving performance, I thought about setting display: none; to the content of the divs above and below the viewport, that is, the divs which are not visible (while keeping their heights, obviously):

enter image description here

In order to check if my idea makes any sense I searched SO and I found this question. According to the comments and to the accepted answer, the best strategy is do nothing, since display: none; triggers reflow and may have the opposite effect:

Setting display to none triggers reflow which is completely opposite of what you want if what you want is to avoid reflow. Not doing anything doesn't trigger reflow. Setting visibility to hidden will also not trigger reflow. However, not doing anything a much easier.

However, there is a recent answer (which unfortunately seems more like a comment or even a question) that claims that display: none; is the current strategy used by sites like Facebook, where the vertical scroll is almost infinite.

It's worth mentioning that, unlike OP's description in that question, each visible div in my site is interactive: the user can click, drag, and do other stuff with the div's contents (which, I believe, makes the browser repainting the page).

Given all these information, my question is: does display: none; applied to the divs above/below the viewport improve performance or does it worsen performance? Or maybe it has no effect?

like image 333
Megaptera novaeangliae Avatar asked Jul 03 '20 06:07

Megaptera novaeangliae


People also ask

What effect does display none have?

When you set the display property of an element to none , the element is completely taken off the page and it doesn't have an effect on the layout. This also means that devices like screen readers, which make websites accessible to blind people, wont't have access to the element.

Does display none prevent loading?

Unfortunately not. Any image in an <img> element will load all the time no matter what you do.

What is the difference between display none and visibility hidden?

display:none means that the tag in question will not appear on the page at all (although you can still interact with it through the dom). There will be no space allocated for it between the other tags. visibility:hidden means that unlike display:none, the tag is not visible, but space is allocated for it on the page.

Does display none Remove from Dom?

With display:none, it is effectively removed from the DOM. Hiding DOM elements with CSS is a common task. Some wonder whether they should use visibility:hidden or display:none.


2 Answers

The "display: none" property of an Element removes that element from the document flow.

Redefining that element display property from none to any other dynamically, and vice versa, will again force the change in document flow.

Each time requiring a recalculation of all elements under the stream cascade for new rendering.

So yes, a "display: none" property applied to a nonzero dimensional and free flow or relatively positioned element, will be a costly operation and therefore will worsen the performance!

This will not be the case for say position: absolute or otherwise, removed elements form the natural and free document flow who's display property may be set to none and back without triggering e re-flow on the body of the document.


Now in your specific case [see edited graph] as you move/scroll down bringing the 'display: block' back to the following div will not cause a re-flow to the rest of the upper part of the document. So it is safe to make them displayable as you go. Therefore will not impact the page performance. Also display: none of tail elements as you move up, as this will free more display memory. And therefore may improve the performance. Which is never the case when adding or removing elements from and within the upper part of the HTML stream! enter image description here

like image 117
Bekim Bacaj Avatar answered Sep 19 '22 20:09

Bekim Bacaj


The answer is, like just about everything, it depends. I think you're going to have to benchmark it yourself to understand the specific situation. Here's how to run a "smoothness" benchmark since the perception of speed is likely more important than actual system performance for you.

As others have stated display:none leaves the DOM in memory. Typically the rendering is the expensive part but that's based on how many elements have to be rendered when things change. If the repaint operation is still having to check every element you may not see a huge performance increase. Here are some other options to consider.

Use Virtual DOM

This is why frameworks like React & Vue use a Virtual DOM. The goal is to take over the browser's job of deciding what to update and only making smaller changes.

Fully Add/Remove elements

You could replicate something similar by using Intersection Observer to figure out what's in/out of the viewport and actually add/subtract from the DOM instead of just relying on display:none alone since parsing javascript is generally more efficient than large paints.

Add GPU Acceleration

On the flip side, if the GPU is taking over rendering the paint might not be a performance suck but that's only on some devices. You can try it by adding transform: translate3d(0,0,0); to force GPU acceleration.

Give the Browser Hints

You may also see an improvement by utilizing CSS Will-Change attribute. One of the inputs is based on the content being outside the viewport. So will-change:scroll-position; on the elements.

CSS Content-Visibility (The bleeding edge)

The CSS Working group at W3C has the CSS containment module in draft form. The idea is to allow the developer to tell the browser what to paint and when. This includes paint & layout containment. content-visibility:auto is a super helpful property designed for just this type of problem. Here's more background.

Edit (April 2021) this is now available in Chrome 85+, Edge (Chromium) 85+, and Opera 71+. We're still waiting on Firefox support, but Can I Use puts it a 65% coverage.

It's worth a look as the demos I saw made a massive difference in performance and Lighthouse scores.

like image 39
Bryce Howitson Avatar answered Sep 20 '22 20:09

Bryce Howitson