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
- Render a placeholder container with a fixed height (prevents layout shift).
- Use IntersectionObserver to detect when the container enters the viewport.
- Initialize Lottie only when needed.
- 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