The frame budget is 16 milliseconds
On a 60 Hz screen the browser has about 16 ms to run JavaScript, compute style, lay out, and paint each frame. Miss it and the frame is dropped — the animation stutters, the list hitches, the tap feels late. The Web Almanac and web.dev repeatedly show the mobile main thread is the bottleneck: a task longer than 50 ms is a "long task" (W3C Long Tasks API) that blocks input and directly hurts Interaction to Next Paint (INP, a Core Web Vital since March 2024, with "good" under 200 ms). On phones, processing a scroll or input event can take hundreds of milliseconds, during which the animation is completely stalled. They call that jank.
WebView puts everything on one thread
A WebView renders a page the browser way: one main thread does JS, style, layout, and paint. An animation driven from script — even a simple setData-style update — must cross from the logic layer to the render layer through a serialized bridge: logic runs, JSON serializes, Native forwards, the render side deserializes, paints, then the frame draws. On a low-end device that round trip easily exceeds 16 ms, which is exactly why drag gestures and scrolling animations feel detached from the finger. The architecture has a hard ceiling: the main thread can only do one of "run JS / lay out / paint" at a time.
Skyline runs animation on the render thread
WeChat's Skyline renderer (self-developed, Skia-based, Flutter-like, generally available since base library 3.0.0 in 2023) moves style computation, layout, drawing, and animation off the WebView and into a native rendering pipeline. The decisive change is the worklet: animation and gesture code runs directly on the render thread, reading and writing shared values with zero cross-thread serialization. There is no bridge round trip, so animations track the finger at up to 120 fps instead of stalling at 16 ms. Native components — camera, map, video — render in the same layer as ordinary components (no awkward z-index hacks), and shared-element transitions are built in.
The renderer decides the ceiling
This is not a tuning difference; it is a structural one. A WebView page can mitigate jank with CSS animations, Web Workers, and careful chunking, but it is still fighting a single main thread that must also parse, compile, and execute JavaScript. Skyline removes the WebView from the render path entirely and lets the render thread own animation and gestures. The result is predictable frame pacing on low-end hardware, which is where jank hurts acquisition the most.
Side by side
| Dimension | H5 / WebView | Mini-Program (Skyline) |
|---|---|---|
| Render backend | System WebView (WKWebView / X5) | Self-developed Skia pipeline |
| Animation thread | Main thread (JS + layout + paint) | Render thread via worklet |
| Cross-thread cost | Serialize → Native → deserialize | Zero (in-thread shared values) |
| Frame ceiling | Drops frames past 16 ms | Up to 120 fps, tracks finger |
| Native components | Layer hacks / z-index | Same-layer, correct stacking |
| Shared-element animation | Not native | Built in |
| Gesture system | No native competition | Declarative gesture competition |
What this means for your UI
If your screens live or die by scroll feel, drag interactions, or shared-element transitions — store fronts, galleries, onboarding carousels — the render path is the product. A governed runtime with a native renderer gives you that smoothness by construction, especially on the low-end Android devices that make up most of the global installed base. H5 remains the right tool for content and the open web; the in-host interactive surface should not stutter when it does not have to.
Where Cross Mini App fits
Cross Mini App is the runtime and open catalog for the smooth-render model. You build a mini-program against a standard API surface and it inherits a rendering path where animation and gesture live on the render thread, in every host that embeds it — not a WebView fighting a single main thread. Smooth is designed in, not hoped for. H5 tells the story; the mini-program lets the user feel it.