Improving Site Performance by Optimizing Lottie Animations
Lottie animations are great, but they can negatively impact page performance. Here are a few tips I use to optimize Lottie animations for the web so that page performance is impacted as little as possible.
The Downside of SVG Animation on the Web
When you generate a Lottie animation with the Bodymovin plugin in After Effects, you’re generating a bunch of JSON code in a file. That JSON gets translated to DOM elements on the page.
As a quick primer: DOM elements are the tags you see in the HTML: <div/>, <p>, <h1> tags are each considered DOM elements.
The TL.DR is: This process allows designers (who are generally responsible for creating these files) to generate production code. This is bad.
Recently we ran a Google Lighthouse performance audit. The audit revealed that we had well over 2,000 DOM elements on a page. When we removed a pretty standard Lottie animation file that we received from our creative agency, the DOM elements shrank down to less than 600.
When you have more than 1,500 DOM elements on a page, Lighthouse dings your performance score and throws this red flag:
Too many DOM elements on the page affects the Largest Contentful Paint (LCP) metric, which is a very important metric in Lighthouse.
The more elements there are on a page, the more items have to be parsed out and managed.
It adds up, and you can see the hit our performance score took here in this screenshot:
Sidenote: I couldn’t find a good way to test how many elements there were in a Lottie animation, so here’s what I ended up doing:
- Generate a demo file from Bodymovin and run it in a browser.
- Then in the console, type document.querySelectorAll(“*”).length;
This gives you the total elements in that animation. This number isn’t entirely accurate, but for testing purposes it works great as a baseline.
Sidenote #2: This is pretty far down the article to be mentioning this, but I am a huge fan of the Figma >> AEUX >> After Effects >> Bodymovin >> Lottie workflow for svg animations. It’s incredible and the pros far outweigh the cons — this article is simply covering how to reduce the cons.
3 Things to Optimize
To optimize, basically you want to check 3 things:
- Nesting & Flattening
Nesting & Flattening:
Try to ungroup layers in Figma and flatten files down when possible.
Every component/frame/group in the Figma file is part of the AEUX export/import.
Multiple fills on a shape in Figma? Each one is getting added in AE and exported to CSS.
12 vector paths with the same fill? Add them in one Shape Layer in AE and just use 1 fill.
Kill Masks, etc as much as possible. Goal is to have a file that is as efficient as possible.
You want Scaling and other properties that get translated into CSS to be on the highest layer possible.
Let’s say you have 5 shapes that are in a shape layer. If the shapes are each scaled to 300%, each one of those gets its own CSS transform.
Scaling all the layers down to 100% and then scaling the parent shape layer 300% reduces that by 80%, resulting in identical visuals with only one single transform.
If you’re using identical graphic elements in your animation, try to reuse those — (see screenshot: Frame 7 & 6 are identical but both export out separately). AEUX imports each component separately, but you can replace them in After Effects if possible and optimize a bunch.
Using these tactics, we went from +2,000 DOM elements down to ~1,400 and improved our Google Lighthouse performance score.
Also note the file size dropped by ~60% or so.
Here’s a video I made that walks through this example and demonstrates these optimizations in detail. https://youtu.be/GNWViLXTlSQ.
I freaking love graphics & workflow optimization stuff like this — if anyone wants to nerd out on it please let me know!