Consigna y contexto
Tras un lanzamiento de PWA, algunos usuarios siguen bajo el control de un Service Worker antiguo y cargan JavaScript antiguo con HTML nuevo, lo que provoca ChunkLoadError. Explica el ciclo de vida, las versiones de caché, las pestañas abiertas, skipWaiting, clientsClaim y las ventajas y desventajas de un rollback.
Esta pregunta es adecuada para roles de frontend, web-platform y full-stack. Evalúa la seguridad en los despliegues y la experiencia del usuario sin requerir un framework específico. Las tasas de error y las proporciones de caché obsoleta son datos de práctica, no umbrales universales.
Qué evalúa el entrevistador
Ciclo de vida
El candidato debe explicar install, waiting, activate y el control de la página, especialmente por qué un worker actualizado espera mientras los clientes antiguos permanecen abiertos.
Consistencia de recursos
Separar HTML, JavaScript con hash, datos de API en tiempo de ejecución y entradas de precache. Eliminar una caché antigua no debe romper una página que aún referencia sus recursos.
Estrategia de adopción
skipWaiting puede acelerar la adopción pero puede cambiar el control durante la vida útil de una página. Una respuesta sólida evalúa la compatibilidad y el consentimiento del usuario.
Rollback y observabilidad
Los identificadores de versión, una ventana de expiración, el monitoreo de errores y un worker no-op proporcionan una forma de detener un despliegue defectuoso.
Preguntas para aclarar primero
- ¿El HTML y los recursos estáticos utilizan hashes de contenido?
- ¿La URL y el scope del Service Worker son estables?
- ¿Los usuarios pueden mantener las páginas abiertas durante horas o tener estado sin guardar?
- ¿La API es retrocompatible con ambas versiones de cliente?
- ¿El producto puede solicitar una recarga en un momento seguro?
- ¿La plataforma puede revertir rápidamente el script del worker y el manifiesto de recursos?
Una respuesta de 30 segundos
“Un worker actualizado normalmente se instala y pasa a waiting mientras el worker antiguo controla las páginas abiertas. Primero haría que el HTML, los recursos con hash y los contratos de API sean compatibles entre versiones, y luego decidiría si skipWaiting es aceptable. Usaría entradas de precache con revisión y eliminaría solo las cachés que se sabe que son antiguas durante activate.
La página observaría updatefound y controllerchange, solicitaría una recarga cuando sea seguro y registraría la versión del worker, ChunkLoadError y el tiempo de activación. Ante un lanzamiento fallido, detendría el despliegue o enviaría un worker no-op mientras retengo los recursos anteriores, para luego reparar y avanzar gradualmente.”
Respuesta profunda paso a paso
Paso 1: Dibujar el ciclo de vida
El registro crea un worker en estado de installing. Tras install pasa a waiting; el worker antiguo sigue controlando las páginas existentes. Una vez que los clientes antiguos se cierran o navegan, el nuevo worker se activa (activate) y toma el control.
Paso 2: Hacer los recursos compatibles
El HTML debe hacer referencia a recursos con hash, y las API deben tolerar campos antiguos durante una ventana de migración. Cambiar solo el nombre de una caché no ayuda si las páginas antiguas solicitan fragmentos (chunks) eliminados.
Paso 3: Diseñar las comprobaciones de actualización
Mantén estable la URL del worker. Los navegadores comprueban cambios de bytes en la navegación y el registro; las sesiones de larga duración pueden llamar a registration.update explícitamente, pero no deben hacer sondeos (polling) de forma agresiva.
~~~js const registration = await navigator.serviceWorker.ready; await registration.update(); ~~~
Paso 4: Manejar la espera y las solicitudes al usuario
Estar en espera (waiting) es lo más seguro por defecto. Si se requiere una adopción inmediata, verifica el estado no guardado y la compatibilidad del protocolo, consulta al usuario y luego envía skipWaiting mediante un mensaje controlado. Maneja controllerchange sin crear bucles de recarga.
Paso 5: Limpiar cachés y revertir
Durante activate, elimina solo las cachés que no estén en una lista de permitidos. Mantén una ventana de recursos previos para rollback. Si un lanzamiento es defectuoso, revierte el punto de entrada o envía un worker no-op en lugar de eliminar todas las cachés.
Paso 6: Observar y verificar
Registra la versión del worker, los aciertos de caché (cache hits), el tiempo de activación, controllerchange, los errores 404 de recursos y ChunkLoadError. Prueba pestañas antiguas y nuevas, inicio sin conexión, recarga, despliegue escalonado y rollback.
Respuesta modelo
“ChunkLoadError puede ocurrir cuando un worker antiguo controla una página mientras el despliegue ya ha eliminado los fragmentos que esa página referencia. El nuevo worker espera de forma predeterminada, por lo que no llamaría a skipWaiting globalmente de entrada.
Mantendría una URL de worker estable, usaría recursos con hash y mantendría una ventana de compatibilidad de API. Las revisiones de precache se gestionarían explícitamente y activate eliminaría únicamente las cachés antiguas fuera de la lista permitida. La página detectaría un worker en espera y ofrecería una recarga cuando no haya estado sin guardar; un cambio inmediato requeriría compatibilidad y un manejo cuidadoso de controllerchange.
Desplegaría el lanzamiento por etapas y monitorearía las versiones del worker, los 404 de recursos y ChunkLoadError. Si la versión es defectuosa, detendría el despliegue del punto de entrada o desplegaría un worker no-op reteniendo los recursos antiguos. La recuperación debe cubrir múltiples pestañas, inicio sin conexión, recarga y un rollback completo.”
Errores comunes
- Asumir que install controla inmediatamente cada página.
- Sobrescribir JavaScript sin hash en el mismo lugar.
- Llamar a skipWaiting incondicionalmente y mezclar versiones a mitad de la página.
- Eliminar todas las cachés durante activate.
- Renombrar el script del worker para forzar una actualización.
- Probar solo una página recién abierta, no una pestaña de larga duración.
- Romper la API mientras solo se revierte la entrada del frontend.
- No tener telemetría de versiones del worker ni rollback mediante no-op.
Preguntas de seguimiento
Pregunta de seguimiento 1: ¿Por qué espera un nuevo worker?
El worker antiguo todavía controla los clientes abiertos. El ciclo de vida predeterminado espera a que esos clientes se cierren o naveguen para que el control no cambie de manera inesperada.
Pregunta de seguimiento 2: ¿Cuándo es razonable skipWaiting?
Cuando los recursos y las API son retrocompatibles, no hay un estado importante sin guardar y una recarga inmediata es aceptable. De lo contrario, espera el consentimiento del usuario o la navegación.
Pregunta de seguimiento 3: ¿Cómo se evita el crecimiento ilimitado de la caché?
Usa listas de permitidos de versiones o revisiones y elimina solo las cachés en desuso durante activate. Conserva la versión anterior durante una ventana de rollback definida.
Pregunta de seguimiento 4: ¿Cómo se detiene un worker con errores?
Detén el despliegue del punto de entrada y, si es necesario, despliega un worker no-op o restaura el script que funcionaba correctamente. Mantén disponibles los recursos antiguos mientras se corrige la versión.
Pregunta de seguimiento 5: ¿Cómo se demuestra que la actualización es segura?
Prueba múltiples pestañas, inicio sin conexión, HTML antiguo con recursos nuevos, recargas, avisos de actualización, compatibilidad de API, monitoreo de errores y la ruta de rollback completa.