← Back to list

The death of the loading spinner: How we achieved sub-100ms video playback

Read how our custom video architecture delivers an instant-on experience that rivals TikTok and Instagram.

AIT · 2026-07-07 09:43 · 0 claps · 4.7 min read
#software-engineering #custom-architecture #engineering-excellence #software-architecture #mobile-app-development
Open on Medium ↗
Wiki topics: 🏛️ · Architecture 💭 · Philosophy of Spirit

The death of the loading spinner: How we achieved sub-100ms video playback

In the world of short-form video, milliseconds aren’t just metrics. They are the primary driver of your bottom line. For every second a user spends staring at a loading spinner, the probability of them “bouncing” to a competitor’s app increases exponentially. In a landscape defined by rapid-fire scrolling, the standard “buffer and play” model used by most video players doesn’t just feel slow; it feels like a broken product.

From a business perspective, high latency is a silent killer. It disrupts user engagement, directly reducing total watch time and, by extension, ad inventory and monetization potential. To capture and hold attention in the modern attention economy, we set out to build a video module that rivals the “instant-on” experience of giants like TikTok and Instagram. The goal: Zero perceived latency.

The problem with the “standard” approach

Most mobile applications rely on default players like ExoPlayer or AVPlayer. While these are robust, they are designed for general-purpose streaming. They prioritize playback stability over “instantaneous” starts, often leading to that dreaded 500ms to 1.5s delay — symbolized by the spinning loader — before the first frame appears.

In cross-platform frameworks like Flutter, we have even less granular control over the native player’s internal caching. To hit sub-100ms startup, we had to stop thinking about a video player as a standalone component and start thinking about it as a deeply integrated data-orchestration system.

Technical deep dive: The engineer’s perspective

Image: Architecture Diagram of the Video Module

Image: Architecture Diagram of the Video Module

We sat down with the engineer behind this module to understand the “how” behind the speed. Here is the technical breakdown of the implementation:

The core challenge,” he explains, “is that standard players are too ‘polite.’ They wait for a handshake, wait for the manifest, and then wait for a minimum buffer safety net before they even think about rendering. To hit sub-100ms, we had to take control of the entire pipeline.

1. The HLS Local Proxy & Manifest Injection

Because native players are “black boxes,” we implemented a Local Loopback Proxy (127.0.0.1) to act as an intelligent interceptor. Instead of pointing the player to a remote CDN URL, we point it to our local server.

  • The Hack: When the player requests a manifest, our proxy intercepts it and modifies the playlist on the fly. It rewrites segment paths to point to files we have already pre-cached on the disk.
  • The Result: The player thinks the stream is local, bypassing the DNS lookup, TLS handshake, and network negotiation phases entirely.

2. Solving the “Infinite Bandwidth” Paradox

A side effect of the local proxy is that the player perceives “infinite” bandwidth (since RTT to localhost is near zero). This causes the player to greedily request the highest 4K/1080p resolution, which actually chokes the real mobile network.

  • The Solution: We moved the Adaptive Bitrate (ABR) logic into the proxy and implemented a global Network Throughput Monitor using an Exponential Weighted Moving Average (EWMA) to calculate the user’s real-world bandwidth.
  • Dynamic Variant Pruning: The proxy fetches the real manifest but returns a “sanitized” version to the player, removing any quality variants the user’s current connection can’t actually handle.

3. The “Dual-Stage” Adaptive Delivery

To guarantee the sub-100ms goal, the proxy employs a split-second delivery strategy:

  • Stage 1 (The Sprinter): For the first 2 seconds of any video, the proxy forces the player to take Adaptive LQ Chunks. It calculates the highest resolution that can be delivered instantly based on the user’s current bandwidth, ensuring a lightning-fast “Time to First Frame.”
  • Stage 2 (The Marathoner): Once playback is established, the proxy allows the player to “upshift” to High-Quality (HQ) variants for the remainder of the video.

4. Predictive Priority Queue & Controller Warming

To achieve an “instant-on” feel, we shifted from a reactive loading model to a predictive one. We don’t wait for the user to swipe; we prepare the environment so that the next video is effectively already playing before it even enters the view port.

The Strategic Pre-fetch Queue

We implemented a custom DataSource that manages a multi-tier prioritized queue based on the user’s scroll velocity and position. Instead of downloading full videos, we focus on high-impact fragments:

  • Segment 0 Priority: The system isolates the first 2 seconds (Segment 0) of the next five videos in the feed. These are treated as high-priority “activation packets.”
  • Background Parallelism: While the user is engaged with the current video, a dedicated background thread warms up these initial segments. By the time the user initiates a swipe, the proxy is no longer looking at the network, it’s serving data directly from a local, high-speed cache.

The “Warm Start” Decoder Prime

The most significant bottleneck in mobile video isn’t just the network; it’s the hardware decoder initialization. Creating a new VideoPlayerController and preparing the GPU usually takes 200ms — 500ms. We bypass this with a “Warm Start” strategy:

  1. Invisible Initialization: We initialize the controller for the upcoming video while it’s still off-screen.
  2. The Play-Pause Flip: We programmatically trigger play() on the muted background controller.
  3. Frame Locking: The moment the controller signals that the first frame has been decoded and buffered into GPU memory, we immediately pause() it.

The Result: When the user swipes, we simply call play(). Since the decoder is already primed and the first frame is sitting in the GPU’s front buffer, the video appears to start instantly — zero spinners, and 100% fluidity.

The technical pillars of instant playback

This architecture is supported by four critical pillars:

  1. The Local HLS Proxy: Manages the “lie” told to the player to eliminate network handshakes.
  2. Proxy-Side ABR: Reclaims control over quality selection based on real-time bandwidth calculations.
  3. Adaptive LQ Starts: Strips away the “safety nets” and heavy segments that cause the spinning loader.
  4. Radical Memory Management: A “sliding window” cache that keeps the UI fluid without crashing low-end devices.

Why it matters

This level of optimization creates a value proposition that resonates at every level of the organization:

  • For the Developer: It is an exercise in low-level mastery. Achieving these speeds requires moving beyond high-level APIs and getting under the hood of network protocols, HLS manifest parsing, and manual memory heaps.
  • For the Business: It is a definitive competitive advantage. In the attention economy, “speed is a feature.” Frictionless transitions mean fewer abandoned sessions and higher user satisfaction.
  • For the User: Fluidity drives retention. When the UI moves at the speed of thought, the technology fades into the background, leaving a premium experience that feels like “magic.”

This module is a testament to what happens when you refuse to settle for “out-of-the-box” solutions.

Inspired by the level of engineering? We’re constantly pushing the boundaries of what’s possible in software development. Explore more of our technical deep dives and projects on our blog.


메타데이터
post_id
3bc3e49d6fed
slug
the-death-of-the-loading-spinner-how-we-achieved-sub-100ms-video-playback-3bc3e49d6fed
url
https://medium.com/@asthait/the-death-of-the-loading-spinner-how-we-achieved-sub-100ms-video-playback-3bc3e49d6fed
canonical_url
https://medium.com/@asthait/the-death-of-the-loading-spinner-how-we-achieved-sub-100ms-video-playback-3bc3e49d6fed
author_url
https://medium.com/@asthait
status
ok
fetched_at
2026-07-29 12:35:37