Performant Web Animations

8 Min read

performant-web-animations-featured-image.jpg

November 3, 2022

How we maintained high technical SEO and site performance while delivering a delightful user experience for our customers using custom Lottie animations.

Introduction

As a new online marketplace, we want to attract potential customers to our website. We need to engage users on our site to share our story and explain how our business can benefit them, cleanly and concisely.

Animated illustrations are a proven UX design tool for engaging users. As the adage says “a picture is worth a thousand words”, and we chose to enhance our home page using a series of scroll animations to capture the user’s attention and highlight our services.

Web animations often come at the cost of website performance, however. We needed to find a way to incorporate these animations while maintaining exceptional technical SEO and website performance across all browsers and devices. Check out our previous post all about Perfecting Technical SEO on our site.

Why do animations inhibit performance?

Depending on how the animation is generated, there are a couple of reasons.

Rendering Pipeline

CSS and JavaScript animations affect the browser rendering pipeline. Browser rendering is a complicated process with four sequential steps:

  1. Style: match each HTML element on the DOM with their CSS rules.

  2. Layout: calculate the size and position of each DOM element on the page. All geometry-based CSS properties affect this step, including heightwidthmarginpadding, and font.

  3. Paint: draw each element in its known position. This is often the longest-running task in the pipeline. CSS properties such as color, box-shadow, and background affect this step.

  4. Composite: build the entire picture of all the elements as layers on the page. Some CSS properties such as transform, opacity, z-index, and filter affect this step only.

When you introduce an animation into the rendering pipeline, you are repeating some or all of these steps, often at a rate of 60 times per second! Because of this sequential pipeline, an animation that updates the layout, for example, is more expensive for performance - it will first re-render the layout, then the paint, and then the composite. An animation that only affects the composite step however, will only have to re-render the composite of the page.

Animations that only trigger the composite to update are the cheapest, in terms of performance. In the browser, they are also typically handled by the GPU on a separate thread, the compositer thread, that is separate from the main thread where styling, layout, paint, and all JavaScript are executed. Therefore, these animations are uninterrupted by any long running tasks on the main thread.

File Size

Many websites use animated GIFs. These files offer great cross-platform compatibility but often have large file sizes and cannot be easily optimized or compressed. The large file size of GIFs can increase load times which will negatively impact SEO and user experience.

What are our options?

HTML/CSS

CSS only animations are quick to implement and very performant as long as you use the best practices around the rendering pipeline, as explained in the previous section. They have great cross-platform support and are easy to control and update in your codebase.

The downside to CSS only animations is that they have limited capabilities. Some properties cannot be animated and more complex animations can require code solutions that are less readable and maintainable.

JavaScript

Once animations become more complex, the next logical step is to incorporate JavaScript code to create the animation. JavaScript allows for broader animation capabilities and great cross-platform support. Since the animation is entirely in your codebase, they are easy to control and customize every aspect of the animation.

The downside to the JavaScript approach is that it can be very time-consuming to develop and design to be performant. Since JavaScript animations cause more re-renders of the page than CSS only animations, they are inherently less performant. Coding these animations from scratch can take a significant amount of time, which may outweigh the benefits of having an animation on the page in the first place.

There are also many JavaScript libraries out there that provide animations out of the box. These can help reduce the amount of time it takes to implement animations but these libraries are often quite large and contain bunch of additional code that is unused but still contributes to the final bundle size of your app.

GIF

Another common way to incorporate web animations is by including animated GIFs. GIFs have the benefit that they are a no-code solution that can be created by a designer outside the codebase. Therefore they are simple to incorporate into your web application. GIF animations also require fewer re-renders of the page to play the animation.

While GIFs have good cross-browser compatibility they do not work well for varying screen sizes and devices. The resolution of a GIF is static and does not scale across different screen sizes without becoming pixelated. Additionally, GIFs can have a large file size that cannot be optimized or compressed, leading to a less performant page.

Lottie

A Lottie animation is one of the newest solutions for building performant web animations. Lottie animations are no-code and created outside of the codebase by a designer, similar to a GIF, but are much more scalable and performant than a GIF file. They are written in JSON format, so they have great cross-platform support and the animation resolution is scalable at run-time. Lottie animations can be easily incorporated into any JavaScript application using the Lottie library.

Lottie was hands down the best solution for our scroll animation use case. Read on to learn more about Lottie files and how we implemented them on our website.

What is a Lottie?

Lottie is a lightweight animated graphics format that works for native and web applications. Designers can create and ship animations without the animations having to be re-created by engineers in the codebase. Under the hood, the Lottie library for JavaScript takes animation data exported from Adobe After Effects as JSON and parses the data to render the animation natively on both mobile and web.

Since Lottie files are written in JSON format, a Lottie is on average 600% smaller than a GIF. The most performant version of a Lottie animation is a dotLottie. dotLottie is a file type with the extension .lottie which stores all the information for the Lottie animation, animation instructions and dependent assets, in one place. It archives and compresses the original Lottie animation, thus reducing storage costs by up to 80% when compared to the original Lottie animation.

Lottie animations are inherently more performant than other solutions, but that doesn’t mean you don’t have to consider optimization when building a Lottie animation. Behind the scenes, Lottie generates code from the original designs, effectively putting production code into the hands of the designers. Therefore it is important that developers AND designers on the team understand how to build a performant animation. The following should be considered:

  1. Reduced instances - when building the animation, think about elements that are alike and create a single instance, or component, that can be reused in the animation versus building separate instances from scratch multiple times.

  2. Flatten layers - watch out for unnecessary nested layers, this creates additional DOM elements that serve no purpose but will inhibit performance and SEO scores. Group and flatten nested layers as much as possible.

  3. Avoid nested scaling - remove nested scaling of elements. The parent element should contain the scaling for all the children.

  4. Use Caution when including images - The file size can be dramatically increased with the addition of images such as JPEGs in the animation. Ensure all images are optimized independent of the Lottie animation optimization.

How did we integrate Lottie animations on our site?

Our largest original Lottie animation was 1.3 MB in size, after converting to a dotLottie file, the file size was only 58 KB. Integrating our dotLottie animations into our Next.js application was a very simple code implementation. You can follow the steps below to get started.

Include the dotLottie player library in your application. The unpacked size is 3.14 MB.

yarn add @dotlottie/player-component
// or
npm i @dotlottie/player-component

Add the Lottie script JSX on the page. In our case, the animations are further down the page so we don’t need to load the script until the user scrolls to that section. Thus preventing a performance hit on the initial page load time.

<Script src='<https://unpkg.com/@dotlottie/player-component@1.0.0/dist/dotlottie-player.js>' />

Render the dotLottie in your JSX

<dotlottie-player src='/[file path]/[animation file name].lottie' autoplay />

It’s as simple as that to get started with the dotLottie animations. There are lots of options and customizations for the dotLottie player library as well. You can read more about those here.

Takeaways

  1. Including animations on your site without negatively impacting performance and SEO scores is possible.

  2. For simple animations, always try to create them using HTML and CSS only first. Also, pay attention to how the properties you are animating will impact the rendering pipeline.

  3. For more complex animations, designers can build animations and export them as dotLottie files to ship highly optimized web animations that have cross-platform compatibility and will not inhibit page performance.

Sources

Understanding Web Animation Performance

Web Animation in the Post-Flash Era

Understanding the internals of Lottie - Rendering the Animation File

Optimizing Lottie Animations to Improve Lighthouse PageSpeed Score

Join our inventory mailing list to get early access to our best deals