Actualizaciones de service worker y coherencia de los clientes
Cómo descubrir actualizaciones de un service worker, coordinar estados waiting y active, recargar clientes controlados con seguridad y conservar pruebas de rollback.
BotBrowser Team
Quieres la documentación estructurada de Despliegue?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
BotBrowser puede crear contextos de navegador controlados y exponer el estado de registro y de cliente que observa una prueba. No cambia el algoritmo de actualización del service worker, no convierte por sí solo un worker waiting en active y no decide cuándo una página puede recargarse sin riesgo. La aplicación es responsable del contrato de coordinación; BotBrowser aporta contextos y puntos de observación repetibles.
TL;DR
Una actualización es una secuencia, no una descarga única. Descubre el candidato con ServiceWorkerRegistration.update(), observa los estados installing, waiting y active, identifica qué clientes están controlados y coordina la recarga solo cuando la nueva versión está lista y es compatible con ellos. Registra las identidades de los scripts antiguo y nuevo, los estados de los clientes, la decisión de la persona y el resultado después de recargar. Si la nueva versión falla, detén su promoción, restaura el último script conocido como correcto y verifica la versión anterior con pruebas nuevas. Este flujo no promete que todos los navegadores se actualicen al mismo tiempo.
Contents
- Modelar los estados de actualización
- Mantener coherentes los clientes controlados
- Coordinar una recarga segura
- Conservar pruebas útiles de rollback
- Validar una versión
- Conclusión práctica
Modelar los estados de actualización
Mientras el navegador evalúa un script candidato, mantiene el service worker active existente. Por eso un registro puede exponer tres referencias distintas: installing mientras se instala el candidato, waiting cuando la instalación terminó pero aún no puede tomar el relevo, y active para la versión que atiende a los clientes controlados. Son estados observables, no sinónimos de “el servidor ya tiene el archivo nuevo”.
registration.update() pide al navegador que compruebe si la URL de script del registro tiene una versión más nueva. La referencia de MDN documenta la promesa que devuelve: se resuelve con el registro cuando termina la comprobación y se rechaza cuando no puede completarse. Una promesa resuelta no demuestra que se haya encontrado o activado una versión nueva. Después hay que leer registration.installing, registration.waiting y registration.active, y escuchar updatefound para un candidato que aparezca de forma asíncrona.
El evento statechange del worker que se está instalando es un límite útil para un mensaje visible. installing significa que el candidato aún no está listo para coordinar una recarga. Si ya existe un worker active o clientes controlados, installed puede permanecer en waiting; durante la primera instalación sin worker active pasa a activating y activated. installed no significa active por sí solo. activating es una transición, no una identidad estable de versión. activated demuestra que el registro tiene un worker active nuevo, pero una página todavía puede necesitar una recarga para quedar controlada.
Una tabla pequeña da un único significado a cada transición:
| Estado observado | Interpretación segura | Siguiente acción |
|---|---|---|
installing | Se está preparando un candidato | Mantener la página y esperar statechange |
waiting | El candidato está listo, pero clientes existentes pueden seguir con la versión active anterior | Mostrar una elección de recarga con nota de compatibilidad |
active con controller sin cambios | El registro está active, pero esta página puede seguir bajo la versión anterior | Esperar controllerchange o una navegación deliberada |
controllerchange | Cambió la versión que controla esta página | Conciliar el estado y recargar una sola vez si hace falta |
No deduzcas el estado a partir de una marca de tiempo, una respuesta 200 o una URL de script nueva. El navegador puede comprobar en otro momento y un cliente puede seguir con el controller anterior mientras otro ya avanza.
Mantener coherentes los clientes controlados
navigator.serviceWorker.controller indica qué worker active controla la página, o null cuando no está controlada. Guarda la URL del script del controller o un identificador de versión expuesto por la aplicación junto al estado del registro. Así se distingue entre “el candidato está instalado” y “esta página funciona bajo el candidato”.
Una aplicación con varias pestañas necesita una decisión única sobre cuándo avanzar. Una pestaña puede observar waiting y difundir a los demás clientes controlados una señal neutral de “actualización lista”. Cada pestaña debe mostrar el mismo identificador y permitir posponer la recarga. Una pestaña con un formulario sin guardar no debe recargarse porque otra esté preparada.
El mensaje de actualización debe llevar hechos, no órdenes que oculten una transición: versión candidata, versión del controller actual, estado de preparación e identificador de solicitud. Al recibirlo, cada pestaña vuelve a leer su registro y su controller. Así no actúa con un mensaje antiguo después de que haya llegado otra actualización.
La compatibilidad decide. Si el candidato cambia formatos de respuesta, supuestos de navegación o el protocolo de la página, no debe tomar el relevo de una página abierta sin una migración. Marca “recargar juntas” las versiones que no pueden coexistir. Una versión compatible puede mostrar un aviso menos intrusivo, pero también necesita comprobar el controller explícitamente.
BotBrowser puede abrir contextos controlados separados y capturar el estado de cada página. No puede hacer que dos contextos compartan un controller ni decidir si el protocolo de una aplicación es compatible. La prueba debe declarar qué clientes avanzan juntos y cuáles pueden quedarse en la versión anterior.
Coordinar una recarga segura
Primero anuncia que la actualización está lista en la interfaz, sin forzar la navegación. Incluye la versión candidata y un motivo breve. Mantén la elección hasta que la página sea segura: sin formulario, carga, pago u otra operación sin guardar que se pierda. Ofrece una ruta de navegación posterior para quien elija “más tarde”.
Después confirma el estado justo antes de recargar. Lee registration.waiting, el worker active y navigator.serviceWorker.controller, y compara sus identificadores con el mensaje que abrió el aviso. Si no coinciden, cierra el aviso y vuelve a comprobar en vez de recargar con información antigua.
Por último coordina la transición. La página puede escuchar controllerchange, dejar de aceptar trabajo nuevo, conservar solo el estado de aplicación que el producto ya permite y recargar una vez. Usa una marca por página para evitar un bucle ante varios eventos. Una página que recibe controllerchange después de iniciar la navegación debe terminarla y registrar el controller resultante.
Esta secuencia mínima observa el estado; no fuerza la activación:
let reloadIssued = false;
let reloadApproved = false;
function approveReload() {
reloadApproved = true;
}
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (reloadIssued || !reloadApproved) return;
if (document.querySelector('[data-unsaved-work="true"]')) return;
reloadIssued = true;
window.location.reload();
});
async function checkForUpdate(registration) {
await registration.update();
return {
installing: registration.installing?.state ?? null,
waiting: Boolean(registration.waiting),
active: registration.active?.scriptURL ?? null,
controller: navigator.serviceWorker.controller?.scriptURL ?? null,
};
}
La política de activación debe ajustarse al protocolo de la página y al trabajo actual de la persona. En formularios críticos, deja terminar y confirma el controller después de la siguiente navegación; en una interfaz de solo lectura puede ofrecerse una elección inmediata cuando la compatibilidad esté demostrada.
Conservar pruebas útiles de rollback
El rollback es una decisión de versión respaldada por observaciones. Conserva la identidad del script conocido como correcto, la identidad candidata, la versión del navegador, el identificador del contexto y el recorrido que falló. Añade horas para descubrimiento, activación, cambio de controller y fin de recarga. Las pruebas necesitan transiciones, no datos de cuenta ni cuerpos de petición.
| Punto | Prueba que se conserva | Decisión |
|---|---|---|
| Antes de promover | Identidad conocida como correcta y resultado aprobado | La base se puede restaurar |
| Descubrimiento | Resultado de update(), estados del registro e identidad candidata | El candidato fue observado realmente |
| Después de recargar | Identidad del controller, versión de página y resultado | El cliente avanzó de forma coherente o no |
| Después del rollback | Identidad restaurada y nuevo resultado del recorrido | El rollback funciona, no solo está configurado |
Cuando falla un recorrido, detén la promoción y compara la identidad del controller con la versión esperada. Restaura el script conocido como correcto mediante la ruta normal de versión, abre un contexto nuevo y repite el mismo recorrido. Un cliente que ya estaba controlado por el candidato puede necesitar una navegación coordinada para demostrar la versión restaurada; regístralo y no declares el rollback antes de tiempo.
Que el archivo antiguo siga accesible no es una prueba de rollback. La prueba es un cliente controlado que informa de la versión active restaurada y supera el recorrido que falló. Conserva el candidato y el registro del fallo para el diagnóstico, mientras la ruta pública sirve solo la versión aceptada.
Validar una versión
En un contexto repetible, cubre la secuencia completa:
- Carga la base y registra el registro, el script active, el controller y el resultado de un recorrido representativo.
- Despliega el script candidato y llama a
registration.update()desde una página ya controlada. - Registra
installing,waiting,active,updatefoundystatechangehasta que el candidato quede estable. - Abre un segundo cliente controlado y confirma si conserva el controller antiguo o avanza según la regla de compatibilidad.
- Elige recargar en un cliente, captura
controllerchangey verifica que la página recarga como máximo una vez. - Repite el recorrido y compáralo con la base. Una diferencia pausa la promoción.
- Ejecuta el rollback con la misma matriz de contextos y conserva la prueba de la versión restaurada.
BotBrowser hace repetibles estas comprobaciones en contextos controlados y versiones de navegador diferentes. No certifica el contrato de compatibilidad de la aplicación, no elige el momento de recarga de la persona y no garantiza un calendario universal de actualización. Esas afirmaciones requieren pruebas propias de las páginas y de la versión.
Consulta Validación de versiones del navegador para la línea base general y Recuperación de sesiones tras una interrupción de red para la recuperación de una sesión.
No escriba solamente “actualización correcta”. Para cada contexto registre la versión del navegador, la URL del script, installing, waiting, active y el controller antes y después del aviso. Registre también si la persona eligió “ahora” o “más tarde”, porque posponer es un resultado válido. Una etiqueta de éxito no distingue entre candidato instalado, worker activo y página controlada.
Compare identidades concretas, no solo nombres visibles. Una URL de script con un identificador de lanzamiento inmutable da al sitio y a la prueba algo verificable. Si la identidad mostrada por la página no coincide con la del controller, conserve la página actual y vuelva a leer el estado en lugar de forzar la navegación. Registre cada pestaña por separado, ya que pueden tener estados y controllers distintos.
Ponga un límite a los reintentos. Llame otra vez a update() solo después de que termine la promesa anterior y anote el número de comprobaciones. Las llamadas repetidas no aceleran la activación y un bucle sin límite puede ocultar un problema de servidor o compatibilidad. Al alcanzar el límite, conserve el estado observado y tome la decisión de lanzamiento.
El texto de la interfaz debe corresponder al estado. Use “hay una nueva versión” solo después de observar waiting o una identidad active nueva; mientras update() está pendiente, diga que se está comprobando. Si la promesa se rechaza, explique que la comprobación no terminó y mantenga utilizable la página. Desactive “recargar ahora” durante una carga o un pago, y vuelva a comprobar antes de navegar.
El registro de aceptación debe ser legible para alguien que no ejecutó la prueba. Incluya el recorrido de la página, cada cambio de controller y un resultado explícito de rollback, con la identidad conocida como correcta y un nuevo recorrido exitoso. Evite volcados de consola y contenido sensible para que el resultado se pueda comparar entre contextos.
El soporte también debe registrar si la página emitió controllerchange. Una comprobación en segundo plano solo debe actualizar el indicador y la instantánea del registro, nunca descartar el trabajo de la persona. Las comprobaciones del navegador durante una navegación deben entrar en el mismo modelo de estados.
Use un vocabulario estable: “candidato” para installing o waiting, “active” para la referencia active del registro y “controller” para la versión que controla la página. Si se rechaza un candidato, registre el estado del fallo y asigne una identidad nueva al siguiente candidato para no mezclar las pruebas.
La aceptación debe responder si update() terminó y se observó la identidad, qué clientes avanzaron según la regla, si se confirmaron las identidades sin trabajo protegido, si hubo como máximo una recarga y si la identidad conocida como correcta junto con un recorrido nuevo prueban el rollback. El resultado solo vale para la matriz declarada y debe repetirse cuando cambien el script o el protocolo.
Conclusión práctica
Trata las actualizaciones del service worker como una coordinación entre un registro, un candidato, una versión active y los clientes que controla. Usa update() para descubrir cambios, lee los estados reales, declara la compatibilidad y permite que cada cliente recargue solo después de confirmar la transición. Vincula la prueba de rollback a un controller real y a un recorrido repetible. BotBrowser reproduce esas observaciones; la política de actualización sigue siendo de la aplicación.
Sources
Artículos Relacionados
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.