Na web aberta, Canvas e WebGL alimentam candlesticks, livros de ordens ao vivo e visualizações 3D de posições suaves. Dentro de um WebView engasgam ou morrem. O WebView do Android cai no render por software a menos que a aceleração de hardware esteja ativa no nível da janela — e canvas.getContext('webgl') retorna null quando não está. O iOS mata em silêncio o processo GPU do WebKit sob pressão de memória sem disparar webglcontextlost, então a cena fica preta enquanto o JavaScript continua rodando. Um runtime de propriedade do host conecta a render nativa — gráficos e visualizações ficam a 60fps em cada motor.
Android: render por software por padrão, WebGL depende da janela
O WebView do Android suporta dois modos: uma camada de hardware que usa a GPU (necessária para WebGL) e uma camada de software que usa a CPU. O tipo de camada padrão é LAYER_TYPE_NONE, e o crucial é que o WebView herda o estado de aceleração de hardware da janela. Se a activity ou a janela desliga a aceleração — um ajuste comum em Unity/jogos/embutidos — o WebView cai em silêncio na rasterização por CPU, e getContext('webgl2') / getContext('webgl') retorna null. O conserto não é só android:hardwareAccelerated="true" no manifest; a janela do próprio WebView precisa estar acelerada, e setLayerType(LAYER_TYPE_HARDWARE, null) é a saída explícita. Mesmo habilitado, a perda de contexto GPU ao trocar para segundo plano obriga a um redesenho explícito, ou aparece uma tela preta.
iOS: o processo GPU morre sem avisar
No WKWebView a renderização roda em um processo GPU do WebKit separado. Sob pressão de memória o iOS mata esse processo — e não dispara webglcontextlost. O app continua ativo, o JavaScript continua rodando, o HUD continua vivo e o gráfico está preto. O iOS 16+ também endureceu os limites de WebGL: recursos de origem cruzada (shaders e texturas em CDN) são bloqueados por padrão por limitsNavigationsToAppBoundDomains = YES, forçando um downgrade para render por CPU e quedas de frames visíveis. O resultado prático: uma cena Three.js / PixiJS a 60fps no Safari arrasta ou fica preta dentro do WebView.
O que quebra quando a render engasga
- Candlesticks e livros de ordens engasgam. Os gráficos de velas, livros e tickers das corretoras perdem frames, então os traders leem preços obsoletos ou atrasados.
- Posições e carteiras 3D congelam. As visualizações WebGL de posições, superfícies de risco e mapas ficam pretas ao rolar ou sob pressão de memória.
- Bateria e calor disparam. A rasterização por software de Canvas/WebGL na CPU consome bateria e aquece o aparelho.
- A armadilha de "no meu desktop funciona". Cada uma dessas falhas só aparece no dispositivo, nunca no Chrome de desktop.
A solução do runtime
Um runtime de propriedade do host conecta a camada de render. Para visualização pesada o host oferece um gráfico nativo / superfície GPU que a página controla via runtime.renderChart() ou uma view nativa; para Canvas/WebGL garante o contexto acelerado e trata a recuperação de perda de contexto. A página mantém seu código de gráficos declarativo; o runtime garante a GPU. Uma integração, cada motor, um frame fluido no fim.
| Dimensão | WebView | Runtime de propriedade do host |
|---|---|---|
| WebGL Android | Downgrade por software; getContext('webgl') null se a janela estiver desligada | Camada de hardware garantida |
| GPU iOS | Processo morto, sem webglcontextlost | Superfície nativa + recuperação |
| Recursos de origem cruzada | Bloqueados por domínios app-bound | Carga nativa / empacotada |
| Taxa de frames | Quedas, tela preta | Alvo 60fps |
| Perda de contexto | Tela preta silenciosa | Observável, recuperável |
| Consistência | Por motor | Uniforme |
Um app nativo renderiza seus gráficos na GPU em todos os dispositivos. Um WebView padrão em quase nenhum. Um runtime dá à página um caminho de render — e um frame no qual confiar.
Fontes
- Android WebView — Aceleração de hardware e tipos de camada — a render do WebView depende do estado de aceleração de hardware da janela; o downgrade por software quebra o WebGL.
- Android WebSettings — setLayerType / render por camadas —
LAYER_TYPE_HARDWAREé o caminho explícito para habilitar a composição GPU para WebGL. - Apple Developer — WKWebView — WKWebView roda o WebKit em um processo separado; o iOS gerencia o processo GPU sob pressão de memória.
- DEV Community — Publicar um jogo Three.js no iOS (morte do processo GPU) — o iOS mata o processo GPU do WKWebView sem disparar
webglcontextlost; o downgrade por software é silencioso. - CSDN — Desempenho WebView Three.js / aceleração de hardware — Android WebView usa render por software por padrão; WebGL precisa de
LAYER_TYPE_HARDWAREpara evitar contexto null.