Why We Chose HTML Video Over Lottie for a Complex Web Animation

This article examines how a complex brand‑page animation was implemented by evaluating GIF, Lottie, APNG, and HTML video options, ultimately choosing a lightweight MP4 video and detailing the numerous mobile‑browser compatibility challenges and React code needed to achieve reliable autoplay.

Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Why We Chose HTML Video Over Lottie for a Complex Web Animation

In the Penguin Tutoring brand page we needed to implement a complex animation that plays when the page scrolls into view.

We considered several frame‑animation solutions:

GIF animation – simple but low quality for large, detailed animations, so it was discarded.

Lottie – uses bodymovin to export After Effects animation as JSON and renders with lottie‑web. Initial tests showed color, tilt and dash‑line differences, so we abandoned it for this case.

APNG – provides better quality than GIF but the files were huge (29 MB) and required a polyfill for browsers that do not support it.

HTML video element – a lightweight MP4 (≈350 KB) that meets the visual requirements.

After trials we chose the video tag. The implementation needed to address several compatibility issues on mobile browsers:

Autoplay is blocked on Safari and Chrome unless the video is muted; we add the muted attribute.

Hide the control bar by omitting the controls attribute.

Enable inline playback on iOS with playsinline and webkit-playsinline.

WeChat on Android does not allow autoplay; we trigger playback on scroll or touch events and fall back to a frame‑by‑frame image sequence when autoplay fails.

Some Android browsers return a resolved promise from video.play() even though the video does not start (e.g., Huawei Honor 8 in WeChat).

Key code snippets (React example):

<video
  muted
  src="***"
  preload="auto"
  playsInline
  webkit-playsinline="true"
  mtt-playsinline="true"
  loop
  ref={this.videoRef}
/>
playVideo = () => {
  const { isVideoCanAutoPlay, isPlayedVideo } = this.state;
  const videoDom = this.videoRef.current;
  if (videoDom && !isPlayedVideo && isVideoCanAutoPlay) {
    const playPromise = videoDom.play();
    if (playPromise) {
      playPromise
        .then(() => {
          this.setState({ isPlayedVideo: true });
        })
        .catch(err => {
          badjs.info(`[Brand Page][AI VIDEO]: autoplay error ${err}`);
          ++this.catchVideoErrorCount;
          if (this.catchVideoErrorCount >= 2) {
            this.setState({ isVideoCanAutoPlay: false });
          }
        });
    }
  }
};

Final takeaways:

Mobile web video autoplay is unreliable, especially on Android browsers.

If autoplay is blocked, user interaction (touch) is required to start playback.

The video.play() promise may resolve without actual playback on some devices.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendLottiemobile compatibilityWeb animationhtml video
Tencent IMWeb Frontend Team
Written by

Tencent IMWeb Frontend Team

IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.