On the open web, Canvas and WebGL power smooth K-line charts, live order books, and 3D position visualizations. Inside a WebView they stutter or die. Android's WebView falls back to software rendering unless hardware acceleration is enabled at the window level — and canvas.getContext('webgl') returns null when it isn't. iOS silently kills the WebKit GPU process under memory pressure without firing webglcontextlost, so the scene goes black while JavaScript keeps running. A host-owned runtime bridges native rendering — charts and visualizations stay at 60fps on every engine.
Android: software rendering by default, WebGL needs the window
Android WebView supports two modes: a hardware layer that uses the GPU (required for WebGL), and a software layer that uses the CPU. The default layer type is LAYER_TYPE_NONE, and crucially WebView inherits the window's hardware-acceleration state. If the activity or window turns acceleration off — a common Unity/Game/embedded setup — WebView silently drops to CPU rasterization, and getContext('webgl2') / getContext('webgl') returns null. The fix is not just android:hardwareAccelerated="true" in the manifest; the WebView's own window must be accelerated, and setLayerType(LAYER_TYPE_HARDWARE, null) is the explicit escape hatch. Even when enabled, GPU context loss on background switches forces an explicit redraw, or you get a black screen.
iOS: the GPU process dies without telling you
In WKWebView the rendering runs in a separate WebKit GPU process. Under memory pressure iOS kills that process — and it does not fire webglcontextlost. The app stays up, JavaScript keeps ticking, the HUD stays alive, and the chart is black. iOS 16+ also tightened WebGL limits: cross-origin resources (CDN-hosted shaders, textures) are blocked by limitsNavigationsToAppBoundDomains = YES by default, forcing a downgrade to CPU rendering and visible frame drops. The practical result: a Three.js / PixiJS scene that runs at 60fps in Safari crawls or black-screens inside the WebView.
What breaks when rendering lags
- K-line and depth charts stutter. Broker candlestick charts, order books, and tickers drop frames, so traders read stale or lagging prices.
- 3D positions and portfolios freeze. WebGL visualizations of holdings, risk surfaces, and maps go black under scroll or memory pressure.
- Battery and heat spike. Software rasterization of Canvas/WebGL on the CPU burns battery and warms the device.
- "Works on my desktop" traps QA. Every one of these failures only appears on-device, never in desktop Chrome.
The runtime fix
A host-owned runtime bridges the rendering layer. For heavy visualization the host offers a native chart / GPU surface the page drives through runtime.renderChart() or a native view, and for Canvas/WebGL it guarantees the accelerated context and handles context-loss recovery. The page keeps its declarative chart code; the runtime guarantees the GPU. One integration, every engine, a smooth frame at the end of it.
| Dimension | WebView | Host-owned runtime |
|---|---|---|
| Android WebGL | Software fallback; getContext('webgl') null if window off | Guaranteed hardware layer |
| iOS GPU | Process killed, no webglcontextlost | Native surface + recovery |
| Cross-origin assets | Blocked by app-bound domains | Bundled / native load |
| Frame rate | Drops, black screens | 60fps target |
| Context loss | Silent black screen | Observable, recoverable |
| Consistency | Per-engine | Uniform |
A native app renders its charts on the GPU on every device. A stock WebView renders them on almost none. A runtime gives the page one rendering path — and a frame it can trust.
Sources
- Android WebView — Hardware acceleration and layer types — WebView rendering depends on the window's hardware-acceleration state; software fallback breaks WebGL.
- Android WebSettings — setLayerType / WebView layered rendering —
LAYER_TYPE_HARDWAREis the explicit path to enable GPU compositing for WebGL. - Apple Developer — WKWebView — WKWebView runs WebKit in a separate process; iOS manages the GPU process under memory pressure.
- DEV Community — Shipping a Three.js game to iOS (GPU process death) — iOS kills WKWebView's GPU process without firing
webglcontextlost; software-render fallback is silent. - CSDN — WebView Three.js performance / hardware acceleration — Android WebView defaults to software rendering; WebGL needs
LAYER_TYPE_HARDWAREto avoid null context.