Llamarlo «WebView» esconde lo que es. No es un rectángulo barato que dibuja tu HTML; es un motor de navegador completo cargado en memoria —y una app de tráfico que abre uno por mini-programa alojado está pagando la renta de ese motor una y otra vez. La factura llega como una pantalla en blanco, un reinicio y un usuario que no vuelve.
Dos plataformas, el mismo impuesto
En Android, la propia documentación de Google es franca: WebView «tiene una huella de memoria significativa» porque es esencialmente un motor de navegador Chromium completo con una arquitectura multiproceso compleja. El contenido web corre en un proceso renderizador aislado en sandbox; el proceso de la app solo aloja la vista y la lógica del lado del navegador. En iOS, cada WKWebView levanta su propio proceso WebContent. Como dice la firma de confiabilidad móvil Embrace, crear un WebView significa «lanzar otra aplicación dentro de tu app móvil y agregar dos procesos adicionales». No hay economías de escala: un WebView son tres procesos del SO, dos son cinco, tres son siete. Cuantos más creas, más lento —y más cerca de un kill.
Los números no son pequeños
Un WebView en blanco no es gratis. Las huellas medidas sitúan una página en blanco en unos 50–80 MB en Android y 50–70 MB en iOS; una lista simple en 100–120 MB / 80–100 MB; una página de detalle de e-commerce en 150–200 MB en Android y 120–150 MB en iOS; una pantalla de live-stream o SPA en 180–300 MB. El ejercicio MemoryLab de Google muestra un proceso renderizador saltando a unos 55 MB tras solo unas pocas asignaciones de JavaScript. Una prueba de estrés documentada de una plataforma de mini-programas encontró que cada instancia de WebView es un proceso WebKit separado con una base de 80–150 MB —«esta sobrecarga es de WebKit, no nuestra, y ninguna bandera la hace más pequeña».
El crash que no puedes reproducir
Aquí es donde se convierte en un incidente de estabilidad. En esa misma prueba de estrés de mini-programas en un build de release de iPhone 15, un WebView en segundo plano era estable, cinco eran estables, pero diez fueron jetsammed —muertos por el sistema en aproximadamente un segundo, con la memoria total del host en torno a 1.0–1.2 GB. La proyección es brutal en dispositivos pequeños: un iPhone SE (3.ª gen, 4 GB) soporta solo uno o dos; un SE (2.ª gen, 3 GB) soporta cero o uno. En iOS, superar el límite de memoria duro del proceso WebContent hace que el sistema lo mate sin negociación —el usuario ve una pantalla en blanco. En Android, el asesino de poca memoria termina el renderizador de forma independiente, y sin manejo obtienes la misma pantalla en blanco al volver. La regla de Embrace: nunca mantengas más de dos WebViews en memoria para un carrusel. Para una app de tráfico que aloja cientos de pantallas de comerciantes, una página pesada basta para hacer OOM a toda la app —reinicio forzado, sesión perdida, carrito perdido, fuga.
La solución del runtime
Un runtime de propiedad del host se niega a levantar un motor de navegador completo para cada programa. En lugar de que cada mini-programa sea su propio proceso de WebView pesado, el runtime agrupa y recicla un conjunto acotado de vistas, comparte un proceso de renderizado donde la plataforma lo permite, y da al programa ligero común —un checkout, un formulario, una tarjeta de contenido— una huella mucho menor a través de un único contexto de runtime compartido en lugar de N motores independientes. El host impone un presupuesto de memoria por mini-programa y en todo el catálogo, recicla instancias en lugar de filtrarlas, y degrada con gracia en lugar de ser jetsammed. Una página pesada de un comerciante deja de poder llevarse toda la app con ella.
| Dimensión | WebView | Runtime de propiedad del host |
|---|---|---|
| Costo por pantalla | Motor completo; 50–200+ MB cada una | Runtime compartido; acotado, agrupado |
| Escalado | Sin economías; N motores = N× sobrecarga | Un contexto compartido; tope por programa |
| Peor caso | Jetsam / kill del renderizador → pantalla en blanco | Presupuesto impuesto; degradación con gracia |
| Radio de blast | Toda la app OOM por una página pesada | Aislado por mini-programa |
| Ciclo de vida de instancia | Fuga si no se destruye a mano | Agrupado, reciclado por el host |
El hilo conductor de esta serie es el control. Un WebView te deja abrir una pantalla pero entrega la factura de memoria —y el crash— al sistema operativo. Un runtime te deja fijar el presupuesto tú mismo. Para una plataforma cuyo catálogo son cientos de páginas de otros, ese presupuesto es la línea entre una app fluida y una pantalla en blanco en un teléfono de gran venta.
Fuentes
- Android Developers: WebView y memoria — WebView es un motor Chromium completo con huella significativa y un proceso renderizador aislado en sandbox.
- Embrace: por qué WKWebView es tan pesado y filtra — cada WebView lanza otra app dentro de la tuya más dos procesos extra; sin economías de escala; limita carruseles a dos.
- MentraOS: prueba de estrés de WebView de mini-programas (10 WebViews jetsammed en ~1s) — cada instancia es un proceso WebKit separado con base de 80–150 MB; dispositivos tipo iPhone SE soportan 0–2.
- Juejin: gobernanza de memoria WebView y OOM en producción — huellas medidas por tipo de página; instancia única 80–150 MB, complejo 200 MB+; tope duro de iOS mata el proceso.
- iOS OOM治理: principio Jetsam y optimización de pico de memoria — el proceso WebContent de WKWebView tiene un límite de memoria más estricto y es matado de forma independiente, apareciendo como pantalla en blanco / crash para el usuario.