Sluggish Animations On Purpose: Part 1
3 min read

Sluggish Animations On Purpose: Part 1

A sluggish animation developed on purpose. And then, a fix that might surprise you


I like the idea of breaking things to understand how they work. With physical stuff, it might be dangerous; if you break it, you might lose it forever. Yet,  it’s easy to break and fix things with software.

In this article, I want to show a sluggish animation developed on purpose. And then, a fix that might surprise you. We will also go into the details of why the solution works.

Sluggish Animation

I created a website with a box that moves from one place to another.

Then, I added a button, that on click, triggers a long and CPU-intensive calculation in Javascript, making the animation sluggish.

Notice how when the top left button is clicked, the animation stops for a moment.

What’s the Problem?

With this example, we learn that heavy JS executions affect style animations.

We find the answer in the MDN docs:

By default, the browser uses a single thread to run all the JavaScript in your page as well as to perform layout, reflows, and garbage collection.


I can think of two different approaches to solve this problem. One involves improving JS execution and the other improving our animation.

In this article, I want to solve it with CSS. In another article, we’ll solve it with Javascript.

CSS Animation

Let’s look at the animation again:

It moves from top left to bottom right. Therefore, we used animations on the “top” and “left” CSS rules.

.box {
  // ...
  animation: move 3s ease infinite;

@keyframes {
  50% {
    top: (300px - 60px);
    left: (300px - 60px);

How Does the Browser Render the Animation?

The browser renders the website at sixty frames per second. That’s once every sixteen milliseconds. On every frame, the browser might need three different steps: “Recalculate Style,” “Layout,” and “Paint.”

From MDN Docs:

  • Recalculate Style: every time a CSS property for an element changes, the browser must recalculate computed styles.
  • Layout: next, the browser uses the computed styles to figure out the position and geometry for the elements. This operation is labeled “layout” but is also sometimes called “reflow.”
  • Paint: finally, the browser needs to repaint the elements to the screen. One last step is not shown in this sequence: the page may be split into layers, which are painted independently and then combined in a process called “Composition.”

These processes are done at the beginning of every website and after CSS changes. Yet, not all CSS modifications trigger all the steps. This is the exciting part.

For example, properties that affect geometry or positioning trigger all the steps. Whereas properties that are rendered in their own layout trigger only one step. You can find the full table of triggers at this link.

Current CSS Animation

Our current CSS animation is done with “top” and “left,” which are properties that affect the positioning of elements. Therefore, the modifications trigger all the rendering steps.

@keyframes move {
  50% {
    top: calc(300px - 60px);
    left: calc(300px - 60px);

On the other hand, the “transform” property triggers only one step, making it a much more performant animation.

@keyframes move {
  50% {
    transform: translate(calc(300px - 70px), calc(300px - 70px));

This is the video of the animations with “transform” instead of “top” and “left”:

You can see how now, clicking the button, does not affect the animation.

Inspect It

Let’s look at the “Performance” tab in the Dev Tools to see how one animation triggers more steps than the other.

Learn to Break It

I learned a lot by building this broken project from the beginning. Real-world projects are complex, and many pieces are interconnected. Therefore, they are not ideal for learning the principles.

Yet, with a simple project that does only CSS animations, we control all the variables that affect the problem and focus on how one thing works.

Don’t be afraid to break things. And build to learn and try things.


If you like this post, consider sharing it with your friends on twitter or forwarding this email to them 🙈

Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it.

And thanks to Michal for reviewing this article 🙏

Thanks for reading, don't be a stranger 👋

GIMTEC is the newsletter I wish I had earlier in my software engineering career.

Every other Wednesday, I share an article on a topic that you won't learn at work.

Join more than 3,000 subscribers below.

Thanks for subscribing! A confirmation email has been sent.

Check the SPAM folder if you don't receive it shortly.

Sorry, there was an error 🤫.

Try again and contact me at llorenc[at] if it doesn't work. Thanks!