Skip to content

Navigation

ServicesAI VideoIndustriesPortfolioPackagesPricingPortalHow We WorkFAQ
START A PROJECT
Web Animation

Lottie vs GIF vs Video: Which to Use on Your Website

A technical comparison of Lottie, GIF, and MP4/WebM for web animation — how each format works, when each one wins, and how to measure the difference yourself.

By Tasnim Ferdous 8 min read
Abstract flat cover: a large coral circle cropped by the right edge, overlapped by a cream ring and a translucent disc on a navy-toned background

Three formats, one animated element on a page, and a decision usually made by habit rather than analysis. The useful way to choose is to understand what each format is at the byte level, because that determines everything downstream — size, sharpness, colour fidelity, CPU cost, and whether your code can talk to the animation at all.

What each format actually is

GIF is a raster format from 1987. It stores a sequence of bitmap frames, each limited to at most 256 colours, compressed with LZW. No inter-frame motion compensation, no modern entropy coding — the root cause of nearly every problem with it.

MP4 and WebM are containers holding video compressed by a modern codec: H.264 or AV1 in MP4, VP9 or AV1 in WebM. Also raster, but they encode the difference between frames, use motion vectors to describe how blocks of pixels move, and decode on dedicated hardware in nearly every device shipped in the last decade.

Lottie is not an image format at all. It is a JSON description of a vector animation — shape layers, paths, transforms, keyframes, easing curves — exported from After Effects and rendered at runtime by a player in the browser. Nothing is pre-rasterised; the browser draws the shapes fresh every frame at whatever size and pixel density the display has.

That is the whole comparison in miniature: Lottie trades storage for computation, GIF and video trade computation for storage.

Sharpness and colour

Because Lottie renders vectors at runtime, it is resolution-independent. The same file is crisp on a 1× laptop, a 3× phone, and a 4K monitor, at any CSS size. There is no "export at 2×" step, because there is no export size.

GIF and video are fixed-resolution rasters. Ship a 400px-wide asset at 400 CSS pixels on a 3× device and the browser upscales it — visibly. The fix is to export at 2× or 3× and scale down, which multiplies file size by the square of the factor.

Colour is where GIF fails hardest. A 256-colour palette cannot represent a gradient, a soft shadow, or a subtle brand colour ramp without dithering — the speckled noise you see across large flat areas in GIFs. Worse, GIF transparency is binary: a pixel is fully opaque or fully transparent. With no partial alpha, every anti-aliased edge is matted against one assumed background colour, so that GIF on a differently-coloured section shows a visible fringe or a jagged edge.

Lottie has full alpha and unrestricted colour. Video codecs have full colour but no usable alpha in practice — support exists, patchily, which is why so many teams end up with a video carrying a hard-coded white background.

File size, and why the usual comparison is misleading

These formats scale along different axes:

  • A GIF grows with pixel dimensions, frame count, and complexity. Duration is expensive because every frame is stored.
  • A video grows with dimensions and duration too, but far more slowly, because inter-frame compression makes a mostly-static scene almost free to continue.
  • A Lottie grows with layer count, path points, and keyframes. Duration is nearly free — a five-second loop and a twenty-second loop of the same complexity weigh about the same — but visual complexity is expensive.

So "Lottie is smaller than GIF" is usually true for the things Lottie is for (icons, loaders, flat illustration) and badly false for things it is not (a traced photograph with thousands of path points, or a base64 PNG embedded inside the JSON).

Beware any comparison table quoting fixed file sizes for "the same animation" across formats. There is no such thing as the same animation across these formats — the numbers depend entirely on the content. Export your own asset in all three and weigh the files.

How to measure it yourself

Export your animation as an optimised Lottie, and as a GIF, MP4, and WebM at display dimensions. Compare on-disk sizes, then load each in a page and read the transferred size in the DevTools Network panel: text-based JSON compresses substantially over the wire with Brotli or gzip while already-compressed GIF and video barely compress at all, so an on-disk comparison overstates Lottie's cost. Then count the player — a JavaScript dependency with its own transfer cost, and if one animation is the only thing using it, that bundle belongs in the comparison.

When video is genuinely the right answer

Lottie advocacy skips this. Use an MP4 or WebM when any of these is true.

  • The content is photographic or filmed. Vectors cannot describe a photograph. Real footage or a screen recording of a real interface is video, full stop.
  • It uses heavy blur, film grain, particle simulation, or gradient meshes. Most of these either do not survive the Lottie export, or survive only by being rasterised into the JSON.
  • It runs longer than a few seconds. Lottie's per-frame rendering cost is paid continuously for as long as it plays. A ninety-second piece is a video.
  • It needs playback controls, buffering, or streaming. That is what <video> is for.

For a background loop, WebM with VP9 is usually the right pick — muted, playsinline, with a poster frame so nothing pops in. The delivery specifications on the process page list the formats we ship as standard, and our video editing and post-production service covers encoding. A product explainer built on real screen recordings sits firmly in this category — see why SaaS companies need explainer videos for how that asset differs from a UI micro-interaction.

When Lottie wins on capability, not just weight

The argument for Lottie that has nothing to do with file size: it is a live object your code can control. Named markers let you play frames 0–30 on hover and 30–60 on click. Bind goToAndStop to scroll position and it becomes a scroll-driven graphic. Being vector data, it can be recoloured at runtime for a dark mode with no re-export. A loader that turns into a success tick when a promise resolves is one animation with two segments, rather than two video files and a swap.

None of that works with a GIF or an MP4 without a separate asset per state.

dotLottie

The .lottie format is a zipped container holding the animation JSON plus any images, fonts, and even multiple animations in one compressed archive. The compression usually makes it meaningfully smaller than the raw JSON, and because assets travel inside the bundle, you cannot ship a JSON referencing image files that never reached the server.

Use it when your player supports it — the dotLottie web component and React player do natively. Keep plain JSON on an older lottie-web setup, on a platform whose Lottie element expects a JSON URL, or in a pipeline that inlines the animation. We deliver both, which is why our Lottie and web motion service lists two output formats rather than one.

SVG renderer versus canvas renderer

This choice decides whether a Lottie feels smooth or janky, and it is an architectural difference, not a setting.

The SVG renderer creates real DOM nodes for every shape and mutates their attributes each frame, so the browser runs style, layout, and paint across all of them. You get crisp scaling and CSS access to the animation's internals — but cost grows with node count, and a busy illustration can mean hundreds of elements recalculated sixty times a second.

The canvas renderer draws to a single <canvas> element. Node count stops mattering, so complex artwork gets dramatically cheaper — at the cost of rasterising at the size it is drawn (you handle device pixel ratio yourself) and losing CSS access to the interior.

Our rule of thumb: SVG for small, simple UI animations and anything that must scale arbitrarily; canvas for busy illustrations, many simultaneous instances, or anything that must hold up on low-end mobile.

How to measure that yourself

Do not take a rule of thumb into production. In Chrome DevTools, open the Performance panel, enable CPU throttling at 4× or 6×, and record while the animation plays. Look at how much of each frame goes to Rendering and Painting, and whether frames blow past your refresh-rate budget. Swap the renderer, record again under identical throttling, and compare. That means something because it is your artwork on your page; someone else's benchmark is not. The same recording tells you whether Lottie or video is cheaper here — video decode largely runs on dedicated hardware and profiles very differently from main-thread vector rendering.

Accessibility applies to all three

A CSS prefers-reduced-motion media query does nothing to a JavaScript-driven Lottie player, and nothing to an autoplaying <video>. Handle it in code:

const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (reduce) {
  renderStaticPoster();
} else {
  player.play();
}

Beyond that: ship a static poster from the resting frame, so reduced-motion, no-JS, and failed-fetch states show the intended composition rather than an empty box. Mark decorative animation aria-hidden rather than inventing alt text for a spinner. Never autoplay sound, and avoid rapid flashing.

The short version

Lottie for anything vector — icons, loaders, empty states, toggles, flat illustrated heroes — and especially where you want runtime control. MP4 or WebM for anything photographic, filmed, screen-recorded, heavily blurred, or longer than a few seconds. GIF essentially never on a production site.

If you are carrying a heavy hero GIF or an autoplaying MP4 that still looks soft, our guide to shipping Lottie without the performance tax covers the loading strategy side of the swap.

RELATED READING