Use Efficient Animated Content: Replace GIFs with Video
Animated GIFs are massive and slow. Learn how to replace them with lightweight video formats and modern animation techniques.
Animated GIFs are a performance disaster. They use an ancient format that was never designed for video — and converting them to modern video formats can cut file sizes by 90-95%.
Why GIFs Are So Expensive
| Content | GIF | MP4 | Savings |
|---|---|---|---|
| 5-second animation | 5MB | 300KB | 94% |
| Product demo | 12MB | 800KB | 93% |
| UI interaction | 2MB | 100KB | 95% |
GIFs store every frame as a full image with limited 256-color palette compression. Video codecs (H.264, VP9) use motion prediction and inter-frame compression — dramatically more efficient.
How to Replace GIFs with Video
Step 1: Convert GIF to Video
Using FFmpeg (free, command line):
# Convert to MP4 (H.264) — best compatibility
ffmpeg -i animation.gif -movflags +faststart -pix_fmt yuv420p \
-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4
# Convert to WebM (VP9) — smaller, modern browsers
ffmpeg -i animation.gif -c:v libvpx-vp9 -b:v 0 -crf 41 output.webm
Online tools: Cloudconvert, EZGif
Step 2: Replace <img> with <video>
<!-- ❌ BAD — massive animated GIF -->
<img src="demo.gif" alt="Product demo">
<!-- ✅ GOOD — tiny video that looks identical to a GIF -->
<video autoplay loop muted playsinline
poster="demo-poster.jpg"
width="600" height="400">
<source src="demo.webm" type="video/webm">
<source src="demo.mp4" type="video/mp4">
</video>
Key attributes:
autoplay— starts playing like a GIFloop— repeats like a GIFmuted— required for autoplay (and GIFs have no sound anyway)playsinline— prevents fullscreen on iOSposter— shows a static frame before the video loads
Step 3: Lazy Load Below-the-Fold Videos
<!-- Don't autoplay until visible -->
<video loop muted playsinline
data-src="demo.mp4"
poster="demo-poster.jpg"
width="600" height="400">
</video>
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const video = entry.target;
const source = document.createElement("source");
source.src = video.dataset.src;
source.type = "video/mp4";
video.appendChild(source);
video.load();
video.play();
observer.unobserve(video);
}
});
});
document.querySelectorAll("video[data-src]").forEach(v => observer.observe(v));
</script>
When to Use CSS Animations Instead
For UI effects, CSS animations are lighter than any image format:
/* Loading spinner — zero network cost */
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e5e7eb;
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
Use CSS animations for:
- Loading spinners and progress indicators
- Hover and transition effects
- Simple motion (fade, slide, scale)
- Decorative background effects
Use video for:
- Screen recordings and product demos
- Complex frame-by-frame animations
- Anything with photographic content
Quick Wins Checklist
- Identify all animated GIFs with
find . -name "*.gif" -size +100k - Convert to MP4 and WebM with FFmpeg
- Replace
<img>with<video autoplay loop muted playsinline> - Add
posterattribute for preview frames - Lazy load below-the-fold videos
- Replace UI animations with CSS where possible
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card