Content-visibility and Web Performance

As web pages get more complex with more use-cases and information, the DOM gets clogged, and, therefore, it renders pages slower than it should. This condition does not work in a competitive market like web development.

On developer forums like Stack Overflow, developers frequently ask questions about reducing the loading and the rendering time of web apps and improve page performance. They do so after exploring every other option they can, like cutting down server response times, shrinking file sizes, and prioritizing file loads. However, all these actions have their downsides and are sometimes outside the control of frontend developers.
A more aggressive approach is to position elements by using the positioning property, and calling an API like getBoundingClientRect():

position: absolute;
left: -10000px;

Although this method does not work all the time, the user agent is still in charge of rendering, styling, and layout of the content. Despite the very negative left value, and depending on its size, the content still shows on the screen.

CSS display and CSS visibility properties

CSS display and CSS visibility properties are popular when it comes to content rendering. They specify the display behavior (type of rendering box) of an element. They are developers’ go-to property for content rendering. Both display: none and visibility: hidden could improve page performance, especially when there is a lot of vertical scrolling and hundreds of DOM page elements.

Display and visibility properties do work but they have major drawbacks.

For display, setting its value to hidden allows an element to not be visible on the webpage. However, it triggers a document reflow, making the browser recalculate the page layout. The reflow causes a problem since the new layout is unplanned, requiring a recalculation that includes all elements under the steam cascade for a new rendering.
Although hidden elements are naturally invisible and occupy no physical space, the size of the DOM does not reduce. Instead, the elements remain in the DOM memory. Hiding them has little effect on performance.
Changing the display property of an element to none also causes the area to be changed. If the repaint area is large, depending on how many elements are hidden, the performance deteriorates due to additional memory going into repainting or reflowing the document.

visibility: hidden works like display: none with a small difference. For visibility: hidden, the document does not reflow. Instead, there is a blank space where the hidden elements are supposed to be.

Page performance and content-visibility

According to W3C Editor's Draft,

Efficiently rendering a website relies on the user agent being able to detect what parts of the page are being displayed, which parts might affect the currently displayed section, and what can be ignored

Browser rendering processing has never been easier with the use of a new CSS property: content-visibility.

Content-visibility enables the user agent to skip an element's rendering work, including layout and painting, until it is needed. Because rendering is skipped, if a large portion of your content is off-screen, leveraging the content-visibility property makes the initial user load much faster. It also allows for faster interactions with the on-screen content

web.dev

Content-visibility is closely related to display and visibility properties, but it also improves their function. However, it operates differently than these two and increases page performance by not rendering the content of the selected elements.

Containment

The key — and the overarching goal — of CSS containment is to improve the rendering performance of web content.
By default, the browser displays everything on a page unless stated otherwise. The contain property works with content-visibility. It allows the developer to indicate that 'an element and its content are, as much as possible, independent of the rest of the document tree.'
When certain elements are isolated or contained from other elements, the browser optimizes the page rendering based on that contained element alone.

There are different types of containment

  • Size
  • Layout
  • Style
  • Paint

Any of the containment can be used with content-visibility property. To read up the different options available for each of the values, please see here for more insights by the CSS Working Group.

Content-visibility values

Content-visibility takes three values – visible, hidden, and auto, along with two global values – initial and unset. For the sake of this article, we will focus on the keyword values.

Visible

Visible does not affect content layout. It is the default value of content-visibility and the page renders normally.

Hidden

How content-visibility: hidden trumps display: none and visibility: hidden.

Content-visibility: hidden is the preferred way to hide elements and boost page performance. It behaves just like display and visibility and combines the best of them. It is more powerful than using either of the properties and its restrictions are strict.
When a webpage with several independent panes is needed to display only one at a time, using display: none means all the style, rendering and layout must be sorted out at once. The content is not omitted, just hidden, so there is a noticeable delay before it comes into view. Accessibility tools also tend to show hidden elements to users.
Visibility: hidden leaves a chunk of space where the element could have been. Although elements are not visible on the webpage, their descendants can show up and set the visibility to visible.

Content-visibility set to hidden is a more reliable and consistent way of hiding elements. When an element is set to content-visibility: hidden, the elements omit the contents of that element. The skipped content is neither selectable nor focusable.

The hidden value takes care of the issues of both display: none and visibility: hidden. Descendants are hidden as well as their parent element. Document styling is preserved, no reflows, and skipped content does not show up anywhere. This means that when the content shows up again, it renders quicker than display or visibility.

<html> 
  <body> 
    <div class="hidden">I am a hidden object </div> 
    <div class="visible"> I am visible </div> 
    <div class="hidden"> I am hidden </div> 
    <div class="hidden"> I am a hidden object </div> 
  </body> 
</html> 
.hidden { 
  content-visibility: hidden; 
  contain-intrinsic-size: 0 500px; 
  /* here we use one of the containment values giving it an intrinsic-size of 0 and 500px. 
  We want the element to be resized as though it had only one descendant of 0 and 500px*/ 
}
.visible { 
  content-visibility: visible; 
  /* to avoid layout shift when switching between .hidden and .visible */ 
  contain: style layout paint; /* this containment takes on style, layout and paint */ 
}

Auto

Auto is the value that shows most promising towards achieving a good page boost. To implement it, we must identify the section and page where we want to use it.

*Note that the effects of content visibility are best seen on a page with long text/sections or a blog.

Auto works just like lazy loading. The major difference is that for lazy loading, the data is not requested until needed, while for content-visibility: auto, the page data loads up but is not rendered until the user scrolls to that point.

<div class="container"> 
  <article> 
    <h1>This is an example of using content-visibility: auto using dummy text <h1> 
  </article> 
  <article> 
    <p>Consectetur adipiscing elit, ipsum dolor sit amet. Mollis blandit nullam faucibus. Integer tristique rutrum rutrum rutrum rutrum rutrum rutrum rutrum rutrum rutrum rutrum rut Non viverra enim, nulla sed varius augue. Sed auctor erat eu fermentum varius sed auctor erat eu fermentum varius sed auctor erat e Ex et elementum, nulla lobortis. Tincidunt nisl nec, facilisis mi. Cras eu nunc blandit, tincidunt nisl nec, facilisis mi. Eu gravida leo sodales ac, donec feugiat nisi nibh. Praesent posuere velit nec feugiat dictum. Nullam acvarius augue. Sed auctor erat eu fermentum varius sed auctor erat eu fermentum varius sed auctor erat e Ex et elementum, nulla lobortis. Tincidunt nisl nec, facilisis mi. Cras eu nunc blandit, tincidunt nisl nec, facilisis mi. Eu gravida leo sodales ac, donec feugiat nisi nibh. Praesent posuere velit nec feugiat dictum.</p> 
  </article> 
  <article> 
    <p>Ipsum ipsum ipsum ipsum ipsum ipsum ipsum ipsum ipsum ips Suspendisse euismod vehicula ligula, malesuada eget suscipit. At magna quis venenatis, vestibulum ultricies. Id in quam non sem quis sem sagittis aliquet. Suspendisse tristique mi, eget ullamcorper sapien nec. Morbi non tempus enim enim enim enim enim enim enim ultricies commodo dolor viverra, curabitur lacinia sem ac diam vehicula. Vivamus commodo varius velit, auctor dui sit amet varius augue. Sed auctor erat eu fermentum varius sed auctor erat eu fermentum varius sed auctor erat e Ex et elementum, nulla lobortis. Tincidunt nisl nec, facilisis mi. Cras eu nunc blandit, tincidunt nisl nec, facilisis mi. Eu gravida leo sodales ac, donec feugiat nisi nibh. Praesent posuere velit nec feugiat dictum</p> 
  </article> 
  <article> 
    <p>Vel sodales elit sollicitudin id, quisque rhoncus sapien quam. Eget sagittis quam tristique, aenean iaculis justo in felis hendrerit. Fusce tempor, enim sit amet tristique gravida, velit ante lobortis erat, et volutpat purus justo sit amet metus, and volutpat purus justo sit amet metus. Preium nunc porta consequat. Maecenas imperdiet euismod tortor, eu mollis nulla sagittis eget maecenas imperdiet euismod tortor. Maecenas ultricies neque sit amet finibus tempor Maecenas ultricies neque sit amet finibus tempor necessitate.</p> 
  </article> 
  <article> 
    <p>Dapibus ultricies maximus quisque. Congue erat quis ultrices etiam egestas. Id diam rutrum, cursus dolor eu, tempus ipsum, Aenean id diam rutrum. In ante lorem, pellentesque id sapien id, lobortis placerat orci, pellentesque id sapien id, pellentesque id sapien id, pellentesque id sapien I mollis nisi dapibus eros fermentum pellentesque integer mollis nisi dapibus eros fermentum pellentesque integer mollis nisi Justo cursus venenatis eu ut elit, ut eget tortor. vulputate massa varius nec, sed sodales dapibus leo. 'Morbi porttitor auctor ornare,' says the narrator. faust</p> 
  </article> 
  <article> 
    <p>Maecenas felis in euismod. At volutpat quam, sed. Pellentesque ac libero eu justo scelerisque porttitor eu vel eros vel eros vel eros vel eros vel eros vel eros vel eros vel eros vel eros commodo in ultrices in, tristique vel sem, lorem massa. A aliquam orci tempus, aliquam porttitor justo ut risus condimentum. Ac augue facilisis dictum nulla sollicitudin felis. Accumsan ligula nam tortor justo, venenatis interdum leo non. pellentesque ne, augue enim. Maecenas felis in euismod. At volutpat quam, sed. Pellentesque ac libero eu justo scelerisque porttitor eu vel eros vel eros vel eros vel eros vel eros vel eros vel eros vel eros vel eros commodo in ultrices in, tristique vel sem</p> 
  </article> 
</div>
body { 
  margin: 2rem; 
  font-family: "Gill Sans Extrabold", sans-serif; 
} 
.container { 
  max-width: 500px; 
} 
article { 
  content-visibility: auto; 
}

Conclusion

Better web performance is one of the most significant benefits of a great UX design. Users always seek the best experience for themselves. In addition to providing convenience when running a responsive site, a high-performance site stands out. Content-visibility has immense potential, promising lucrative benefits for users and contributing to why they will keep coming to your site.

Author

Ivaylo Ivanov

Ivaylo loves Frontend implementations. He is eager to construct interfaces that users love; pixel-perfect. In his day-to-day job, he caters to anything HTML, CSS, SCSS, or JavaScript-based on the frontend side. Complexity is not a problem, he masters VueStorefront implementations equally well to simple web apps or PWAs.
Experimentation with CSS and its' capabilities is Ivo's passion. Be it animated elements, or SVG animations - he loves it!