Jank. It’s a term that’s thrown round quite a bit in the web development world, but what is it exactly? Today, we’ll take a look at what this term means, its causes, as well as a few things that can help us keep it from ruining our the experience of our users.

What is Jank?

Jank is a term that focuses on how a webpage is performing. But instead of being linked to the speed at which the page loads, jank is linked to how smoothly the page renders. Ideally, a site would load quickly, look good, AND be silky smooth. “Jank” is any stuttering or choppiness that a user experiences when there is motion on the screen—like during scrolling, transitions, or animations. So although a website may look incredible and load quickly, if there’s jank—a noticeable choppiness when using the page—this will negatively affect the user experience—something we all want to avoid.

What Causes Jank?

Jank is simply the result of the web page not being able to keep up with the refresh rate of the display. Most devices refresh 60 times/second (60Hz). When there is motion on the screen, the browser should be able to match this refresh rate by creating 60 frames per second. If we break down the time we have to work with (60 frames/second), we see that we have 16.67ms to do any calculations and then render each new frame. If we can’t keep up, the result will be jank.

When there is motion on screen it is typically controlled through JavaScript or CSS. So if there is jank, one cause may be the JS is taking too long to run and not allowing the browser to create a new frame every 16.67ms. It may also stem from which CSS properties of an element are being changed. Some of these properties are more expensive to change than others because they force the browser to recalculate and redraw the entire page, and not just a small section. If this happens too much, it can be difficult to stay within the budget of 16.67ms per frame, and will lead to jank.

Steps in the Rendering Process

When it comes to optimizing a page to reduce jank, it’s important to understand the general process the browser goes through to render something to the screen. Here’s a summary of the steps involved:

  1. Calculate - Determines which CSS rules apply to which elements
  2. Layout - Determines dimensions and positions for each element
  3. Paint - Fills in the pixels for each element onto layers, but doesn’t yet draw these layers screen
  4. Composite - Draws the painted layers to screen

Each of these steps triggers those that come afterward, but not vice versa. So for instance, if the browser has to do the first step, it will have to do the next three. But if it only needs to do the last step, then that’s all it has to do. As you can probably guess, the fewer steps the browser has to take to render the screen the better for performance.

Which CSS Properties to Use?

In light of these steps, the ideal scenario for the browser is that it would only need to deal with the final composite step for any motion on the screen. This would allow it to take the existing layers and re-order or re-position them, without needing to go through the earlier steps of calculating the layout or doing a repaint.

So how do we know which CSS properties will trigger only the composite step and which ones will trigger earlier steps? Thankfully there is a handy list of which CSS properties trigger which steps. If we need to change the properties of an element on screen, the ones we’ll want to try to use are the ones that only trigger the composite step—the ones we’ll want to avoid if possible are the ones that trigger the layout step.

For instance, the transform and opacity properties only trigger the composite step, whereas the top and left properties trigger the layout, paint, and composite steps. So if we want to move an element up by 100px, it will be much more efficient to animate the position by using transform:translateY(-100px) instead of using top:-100px, since the transform property will only trigger a re-composite without triggering the other steps.

This is not to say that these other less efficient properties should never be used, but it is to say that we should be aware of the effect that each property has on the overall performance of the browser.

Make it Smooth

Nobody likes a choppy, stuttering experience when trying to interact with a web page. Even if the page is beautiful, the existence of jank can leave a bad taste with the user. But jank can be controlled. It just takes being intentional about what we’re asking the browser to do every 16.67ms. By auditing what animations are actually necessary, and by using more efficient ways of animating elements when possible, we can give the browser the best shot to be successful at matching the 60 frames/second target—something that all our users will appreciate.