What lazy loading means for Rive
- Don’t initialize the Rive runtime or download the .riv file 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 Rive only when needed.
- Pause when offscreen, play when visible.
Example of Rive animation lazy loading
See the Pen Lazy loading Rive animations by Motio Pix (@motiopix) on CodePen.
<script src="https://unpkg.com/@rive-app/canvas@latest"></script>
<!--
Rive canvas (production use):
Place this canvas anywhere on your page.
This works best on pages that scroll (so the element can enter/leave the viewport).
-->
<canvas id="mp-rive-canvas"
width="300"
height="300"
style="display:block;margin:auto;"></canvas>
<script>
var canvas = document.getElementById('mp-rive-canvas');
var riveInstance = null;
// Load the .riv file only once (lazy load)
function loadRive() {
if (riveInstance) return;
riveInstance = new rive.Rive({
src: 'https://dev.motiopix.com/files/rive.riv', // Replace with your hosted .riv file
canvas: canvas,
autoplay: true
});
}
// Observe when the canvas becomes visible/offscreen
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
// Canvas is visible (or close to being visible)
if (entry.isIntersecting) {
loadRive();
// Resume animation when visible
if (riveInstance) riveInstance.play();
// Canvas is offscreen
} else {
// Pause animation to reduce CPU/GPU usage
if (riveInstance) riveInstance.pause();
}
});
}, {
// 0.2 = 20% of the canvas must be visible before it's considered "in view"
threshold: 0.2,
// Start loading a bit BEFORE the canvas enters the viewport (smoother, less pop-in)
// First value affects top/bottom, second affects left/right
rootMargin: '150px 0px'
});
observer.observe(canvas);
</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 canvas stays blank, it’s often a container size issue or a blocked .riv URL.
- If it works locally but not on your site, check mixed content (HTTPS) and CORS rules.
- If the animation loads but feels heavy, reduce how many canvases run at the same time and pause offscreen ones.
Was this article helpful?
0 out of 0 found this helpful