Oct 14, 2025

by

Anoop

Faster video with HLS in Framer

Fast, reliable video in Framer without layout shifts

If you’ve embedded MP4s directly in Framer, you’ve probably seen slow first paint, random layout jumps, and buffering on weaker networks. It feels clunky and it costs sign‑ups and sales. In this guide, you’ll switch to a lightweight HLS setup with a custom player that loads fast, adapts to bandwidth, and keeps your layout rock‑solid.

Why this happens

  • What you see: pages stall, posters flash, and the video box jumps on load.

  • What the browser does: it guesses a default 300×150 size until it knows the video’s dimensions, and it must download big MP4 chunks before showing anything useful.

  • Why it leads to the symptom: large MP4s delay first paint and interactivity, while missing intrinsic dimensions cause cumulative layout shift. On variable networks, fixed‑quality MP4s either buffer or waste bandwidth.

Short version: bundling MP4s into the project ties authoring to delivery, inflates build size, and blocks adaptive streaming. Streaming separates concerns and lets the player adjust quality in real time.

Embeds: drawbacks and fixes

  • YouTube: Branded controls, suggested videos, and external UI that can distract and leak traffic. Limited control over buffering and preloading. Ads on some setups.

Recommendation: Prefer a custom HLS player with self‑hosted delivery for full UI control and no distractions. If you must use YouTube, delay loading the iframe until user interaction, use a clean poster overlay, and minimize branding to keep focus on the page.

  • Vimeo: Solid platform, but streaming can feel slow and becomes expensive at scale. Player is not fully swappable, so using a truly custom player is difficult.

Recommendation: Move delivery to Bunny.net Streams and play via a custom HLS player for faster starts and lower cost. If staying on Vimeo, lazy‑load the player, use a static poster, and keep the embed off‑screen until needed to reduce JS and network overhead.

  • Raw with MP4: No adaptive bitrate. Large initial downloads, higher buffering on weak networks, and layout shift unless you lock aspect ratio.

Recommendation: Use MP4 only for tiny loops or micro‑interactions, and set width and height plus an aspect‑ratio wrapper to prevent CLS. For primary content, switch to HLS with adaptive bitrate via a custom player.

Why this matters: these defaults trade convenience for control and performance. A custom HLS setup gives you adaptive quality, predictable UI, and fewer distractions.


The solution

You’ll stream with HLS via bunny.net and use a custom player that:

  • Locks aspect ratio on first paint to prevent layout shift

  • Uses native HLS on Safari and hls.js only when needed elsewhere

  • Starts safely, then adapts quality up or down in real time

  • Shows a tiny blurred poster (LQIP) instantly while the first segment loads

What you’ll achieve in one sentence: fast, stable, adaptive video in Framer with minimal code.


Quick start

1) Prepare your source

  • Upload your master video to bunny.net Streams. Bunny will transcode to multiple renditions automatically.

2) Get the HLS URL

3) Add the player to Framer

  • Use your custom component’s props: playlistUrl, poster, muted, autoplay, playsInline.

  • Implement without inline code blocks. In Safari, use native HLS playback. In other browsers, load hls.js only when needed. Initialize the player after mount, and ensure the has intrinsic width and height.

4) Prevent layout shift

  • Wrap the video in a container with a fixed aspect ratio.

  • Set intrinsic width and height on the tag so the browser never guesses 300×150.

5) Load hls.js only when needed

  • Dynamically import hls.js in non‑Safari browsers to keep the bundle lean.

6) Optional: instant blurred poster

  • Generate a tiny LQIP and set as poster to bridge the first frame.

Why this works: HLS slices video into small segments across multiple qualities, so playback can start fast on a modest rendition and step up as bandwidth allows—no restarts, fewer stalls.

Proof: small win in one screen

  • First paint stabilizes because aspect ratio is locked from the start.

  • Time‑to‑first‑frame improves by avoiding large MP4 chunks and using an instant poster.

  • Rebuffering drops on variable networks thanks to adaptive quality.

Variations and trade‑offs

  • Tiny loops or UI micro‑interactions: use my custom MP4 player for seamless looping when the clip is small and needs to play continuously. MP4 or GIF‑like sprites are also fine in these cases.

  • Live or long‑form: prefer HLS for adaptive quality and time‑shift.

  • Security: set CORS on playlists and segments if you capture posters client‑side.

  • Performance: lazy‑load the player and only import hls.js when required.

Extensive use cases

  • Course creators selling on Framer: Keep learners focused with a distraction‑free player, adaptive quality for global audiences, and reliable resume playback. Use per‑lesson posters and preload the first segment for instant start.

  • Heavy marketing sites with many videos: Lock aspect ratios to eliminate layout shift, lazy‑load players below the fold, and stream via HLS to avoid large MP4 downloads. Control UI to match brand and reduce exits.

  • Large video libraries or resource hubs: Serve consistent controls and keyboard behavior across hundreds of items. Use playlist URLs and shared player props to standardize UX and maintenance.

  • Membership or gated content: Pair with Framer Auth and deliver via HLS for steady playback on variable networks. Gate the playlist URL, and load hls.js only when needed to minimize bundle size.

  • SaaS docs and product tours: Short, focused clips that must never stall. Use poster + muted autoplay for quick loops, and fall back to MP4 only for micro‑interactions.

  • Newsrooms and editorial sites: Adaptive bitrate handles spikes in traffic and mixed network conditions. Pre-generate LQIPs to keep pages snappy during peak load.

  • Event pages and webinars: Long‑form and live scenarios benefit from HLS for time‑shift and quality changes without restarts.

Recommended defaults

  • Autoplay muted with playsInline on hero blocks

  • Aspect‑ratio wrapper plus width and height on

  • Native HLS on Safari, dynamic import hls.js elsewhere

  • Tiny LQIP poster for instant paint

  • Defer player init until visible for below‑the‑fold embeds

Best practices

  • Use Fill sizing with a max-width or a fixed width for the video player. This prevents layout shifts and keeps the player visually stable when Auto adjusts bitrate or when a viewer manually changes quality.

FAQ

  • When is a plain MP4 OK? Very short clips, fully offline contexts, or when streaming infrastructure isn’t available.

  • Does Safari need hls.js? No. Safari plays HLS natively. Other browsers use hls.js.

  • Will this add bloat? No, hls.js loads on demand only for non‑Safari users.

Wrap‑up and next step

You now have a stable, adaptive player that fits real pages, not demos. Ship lighter pages, reduce layout shift, and improve watch‑through. Next, dive into the bunny.net setup to tune renditions, caching, and costs.

Related components

HLS video player

$19

HLS video player

$19