What lazy loading means for Lottie

  • Don’t initialize or download the animation until it’s close to the viewport.
  • Pause the animation when it’s offscreen to save CPU/GPU and battery.
  • Resume playback when it becomes visible again.

When you should use it

  • Pages with multiple animations (grids, galleries, long landing pages).
  • Mobile-heavy traffic or performance-sensitive pages.
  • Animations below the fold (not visible on initial load).

When you don’t need it

  • A single small animation above the fold (hero area).
  • One animation on a short page where it’s always visible.

Recommended approach

  1. Render a placeholder container with a fixed height (prevents layout shift).
  2. Use IntersectionObserver to detect when the container enters the viewport.
  3. Initialize Lottie only when needed.
  4. Pause when offscreen, play when visible.

Example of single Lottie lazy loading

See the Pen Lazy loading Lottie animations by Motio Pix (@motiopix) on CodePen.


<script src="https://unpkg.com/@dotlottie/player-component@latest/dist/dotlottie-player.js"></script> <!-- Container for the animation (place anywhere on a scrollable page) --> <div id="mp-lottie-wrapper" style="width:300px;height:300px;margin:auto;"></div> <script> var wrapper = document.getElementById('mp-lottie-wrapper'); var player = null; // Creates and mounts the Lottie player only once function loadLottie() { if (player) return; player = document.createElement('dotlottie-player'); player.src = 'https://dev.motiopix.com/files/lottie.lottie'; // Replace with your hosted .lottie file player.background = 'transparent'; player.speed = '1'; player.style.width = '100%'; player.style.height = '100%'; wrapper.appendChild(player); } // Observe when the container enters or leaves the viewport var observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { // Element is visible (or close to being visible) if (entry.isIntersecting) { loadLottie(); // Resume playback when visible if (player && player.play) player.play(); // Element is no longer visible } else { // Pause playback to save CPU/GPU resources if (player && player.pause) player.pause(); } }); }, { // Percentage of the element that must be visible // 0.2 = 20% of the container is in view threshold: 0.2, // Start loading slightly BEFORE the element enters the viewport // 150px top/bottom buffer for smoother appearance rootMargin: '150px 0px' }); observer.observe(wrapper); </script>

Practical tips

  • Always set a fixed height (or aspect ratio) for the container to avoid layout jumps.
  • Don’t autoplay everything. Start only when visible.
  • If you have many animations, consider pausing all offscreen instances.
  • Use caching headers or a CDN for faster repeat loads.
  • Respect user preferences: if “Reduce Motion” is enabled, consider disabling autoplay.

Troubleshooting

  • If the animation shows blank, it’s often a container height issue.
  • If autoplay doesn’t start on mobile, trigger play on visibility or user interaction.
  • If it loads slowly, the JSON may be large; optimize the animation or use a more efficient delivery setup.
Was this article helpful?

0 out of 0 found this helpful