Debugging for UI Responsiveness in CSS

Some CSS properties and values trigger operations called “reflows” and “repaints”, which can have a negative effect on the responsiveness of the user interface. This is especially true for low-powered devices. Let’s look at how to measure UI performance using browser tools. First, however, let’s define “reflow” and “repaint”.

1. What Are Reflows and Repaints?

A reflow is any operation that changes the layout of part or all of a page. Examples include changing the dimensions of an element or updating its left position. They’re expensive, because they force the browser to recalculate the height, width, and position of elements in the document.

Repaints also force the browser to re-render part of the document. Changing the color of a button when in a :hover state is one example of a repaint. They’re a bit less troublesome than reflows, however, because they don’t affect the dimensions or positions of nodes.

Reflows and repaints are most often triggered by DOM operations—such as adding or removing elements. Changing the values of properties that affect the dimensions, visibility, or position of an element can also trigger reflows and repaints. CSS Triggers is a good (though dated) starting point for identifying which properties may be causing performance bottlenecks.

It’s difficult to completely banish repaints and reflows from a project. We can, however, identify them and reduce their impact using performance tools.

2. Performance Tools

Performance tools measure how well your front end behaves, capturing things like frame rate and asset load times. By recording page activity, we can determine which portions of our CSS may be causing performance bottlenecks.

In Microsoft Edge, Chrome and Firefox, you’ll use the appropriately named Performance panel. Safari calls it Timelines.

There are two ways to trigger the profiling tool:

  • manually by pressing the Record or start button
  • programmatically using profiLe( profiLeName ) , where profiLeName is the optional name for the profile.

To stop recording, press the stop button, or use consoLe.profiLeEnd( profiLeName ) .

Performance tools can be a bit befuddling. Each browser displays its data a little bit differently. To see what this looks like in practice, we’ll compare two basic documents, examples A and B. In both cases, we’re moving a series of <div> elements from an x-position of zero to an x-position of 1,000.

Both examples use CSS animations. In example A, however, we’ll animate the Left property. In example B, we’ll translate our elements by 1,000 pixels and animate the transform property.

Our markup for both is the same:

<!DOCTYPE html>

<html lang=”en-US”>

<head>

<meta charset=”utf-8″>

<title>Performance example</title>

<style type=”text/css”>

/* CSS will go here */

</style>

</head>

<body>

<div></div>

<div></div>

<div></div>

<div></div>

<script type=”text/]avascript” src=toggle-move-class.js></script>

</body>

</html>

The JavaScript for both documents is also the same. When the page loads, we’ll add a running class to the body that triggers our animation:

function startAnimation() {

document.body.classList.add(‘running’);

}

window.addEventListener( ‘load’, startAnimation );

Some of our CSS is common to both examples:

div {

background: #36f;

margin-bottom: 1em;

width: 100px;

height: 100px;

/*

* Shorthand for animation direction,

* duration, timing function, iteration, and play state

*/

animation: alternate 2s ease-in 2 paused;

}

.running div {

animation-play-state: running;

}

For example A, we’ll animate the Left property. Here’s our animation CSS:

@keyframes change_left {

from {

left: 0px;

}

to {

left: 1000px;

}

}

div {

position: relative; /* Element must be positioned in order for left to work */

left: 0;

animation-name: change_left;

}

In Safari, animating the Left property generates lots of layout and rendering operations. It also uses quite a bit of CPU power.

In Chrome and Edge, the profile is similarly red. In this case, however, the uppermost row of red markings indicates dropped frames. Dropped frames can cause what experts call jank, or animations that aren’t as smooth as they can be. The lower row of markings indicates shifts in page layout. These changes may cause performance lags or rendering glitches for devices with limited memory or slower processors. Animating the left property results in lots of dropped frames in Chrome and Edge, as shown below.

The reason for the style recalculations and repaints has to do with the property we’re transitioning: Left . The Left property triggers a reflow whenever it’s changed, even if that change is caused by an animation or transition.

Now, let’s take a look at the CSS for example B:

@keyframes translate_left {

from {

transform: translateX(0);

}

to {

transform: translate(1000px);

}

}

div {

transform: translateX(0);

animation-name: translate_left;

}

This time we’re animating the transform property from a start value of transLatex(0) and an ending value of transLatex(i000px) .

Chrome and Edge drop far fewer frames.

I haven’t yet mentioned Firefox, because Firefox handles both animations similarly. The following image shows the results of animating the left property. Firefox 86 managed an average frame rate of 52.58 frames per second

The next image reflects the performance of animating a translation transform. Firefox 86 had a slightly higher frame rate of 56.56 frames per second

In practice, choose the property that performs best across the broadest range of browsers.

3. Identifying Which Lines to Remove

As mentioned earlier in this chapter, properties that affect the size, geometry, or placement of objects can trigger reflow operations. This includes positional properties like Left , top , right , and bottom , alignment-related properties, and display .

Once you know which properties could cause trouble, the next step is to test the hypothesis. Disable the property—either with a comment, or by adding a temporary x- prefix—and rerun the performance test.

Remember that performance is relative, not absolute or perfect. The goal is improvement: make it perform better than it did before. If a property or effect is unacceptably slow, eliminate it altogether.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *