Una web app se apoya en temporizadores, sondeo y sincronización para mantenerse viva: el chat avanza, los paneles se actualizan, las subidas terminan, los tokens se renuevan. Dentro de un WebView ese contrato se rompe en cuanto la app pasa a segundo plano. Android pausa JavaScript cuando la actividad se pausa; pauseTimers() congela todos los temporizadores del proceso; y en iOS, los propios ingenieros de Apple confirman que el JavaScript de un WKWebView "se pausa/se congela" al pasar la app a segundo plano, por diseño. No hay Background Fetch, no hay Background Sync, no hay keep-alive en el lado del WebView. Un runtime propio del host proporciona un puente real de tareas en segundo plano: programación nativa, deltas empujados por el servidor y puntos de control en primer plano, para que la experiencia sobreviva a la app en segundo plano.
La app pasa a segundo plano y la página se apaga
En Android, WebView.onPause() pausa animaciones y geolocalización, y el ciclo de vida documentado lo empareja con pauseTimers(), que detiene "todo el layout, el parsing y los temporizadores de JavaScript de todos los WebView" de forma global. Una vez en segundo plano, los callbacks de setInterval, los reintentos de fetch y las tareas largas dejan de dispararse. En iOS la respuesta es más contundente: un ingeniero de Frameworks en los foros de Apple dice que esto es "por diseño, por las mismas razones por las que cualquier app suspendida ya no ejecuta código", con solo "unos segundos" de gracia desde iOS 13. WKWebView incluso debe estar en la jerarquía de vistas para ejecutar JavaScript, y las instancias fuera de pantalla o en segundo plano simplemente se inactivan.
Sin background fetch, sin background sync
Las respuestas de la plataforma web para ir offline y volver — Background Fetch, Background Sync y Periodic Background Sync — están ausentes dentro de un WebView. Aunque un navegador independiente las soporte, el WebView no las puentea al sistema operativo. Así, una H5 que encola una subida fallida para "reintentar cuando haya red" no tiene nada que la despierte; un chat que sondea cada tres segundos simplemente se detiene; una renovación de token programada con setTimeout se dispara tarde o nunca.
Qué se pierde cuando la página se congela
- El tiempo real se detiene. Chat, presencia y paneles en vivo dejan de actualizarse en cuanto el usuario cambia de app.
- Subidas y sincronización se abortan. Las peticiones en curso y las escrituras en cola nunca terminan ni reintentan.
- Los tokens expiran en silencio. Una renovación programada en la página se dispara horas tarde, tras morir la sesión.
- Los bucles de reintento mueren. Los temporizadores de retroceso exponencial se congelan; la recuperación solo ocurre al volver a abrir.
- Sin garantía offline-first. La sincronización en segundo plano del Service Worker no existe en WebView (ver "Buzón Silencioso"), y la página no puede compensar.
La solución del runtime
Un runtime propio del host saca el trabajo en segundo plano de la página. Proporciona un puente de tareas nativo por debajo del WebView: el host programa trabajo acotado mediante las APIs de tareas en segundo plano de la plataforma, empuja deltas a la página en primer plano y guarda puntos de control antes de suspender la app. La H5 conserva sus temporizadores para primer plano, pero el runtime garantiza que el trabajo ocurre de verdad: reanudable, observable y no a merced de la pausa inactiva del motor.
| Dimensión | WebView | Runtime propio del host |
|---|---|---|
| JS en segundo plano | Congelado por diseño | Programación nativa |
| Temporizadores (setInterval) | Se detienen al pausar | El puente reanuda en primer plano |
| Background Fetch / Sync | No disponible | Deltas empujados por servidor |
| iOS WKWebView | Suspendido, segundos de gracia | Tarea del host, independiente |
| Reintento de subida / sync | Muere en segundo plano | En cola + reanudado |
| Punto de control de estado | Ninguno | Al suspender / reanudar |
Una pestaña de navegador puede confiar en la plataforma para mantener viva su tarea. Un WebView puro no. Un runtime da a la página un segundo plano en el que confiar: pasar a la pantalla de inicio no significa quedar a oscuras.
Fuentes
- Apple Developer Forums — Ejecución de JS en WKWebView en segundo plano — ingeniero de Apple: suspensión "por diseño".
- AOSP — Buenas prácticas del ciclo de vida de WebView (Cap. 45) — onPause/pauseTimers congelan todos los temporizadores JS.
- Stack Overflow — WKWebView no ejecuta JavaScript en segundo plano — WebView debe estar en la jerarquía de vistas.
- MDN — Background Synchronization API — la solución web que WebView no puentea.
- Apache Cordova — JS en segundo plano poco fiable en WKWebView — iOS pausa, Android no garantizado.