Tema representativo de entrevista

¿Cómo evita el Service Worker navigation preload el retraso de inicio en la primera navegación?

FrontendIntermedio
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Un sitio SSR que utiliza un Service Worker presenta navegaciones iniciales lentas. Explica cómo navigation preload ejecuta la solicitud de red en paralelo con el inicio del Service Worker, cómo manejar preloadResponse, el almacenamiento en caché, los errores y la medición.

Prompt y contexto

Tu sitio intercepta solicitudes de navegación con un Service Worker para ofrecer un fallback sin conexión y almacenamiento en caché compartido. La primera navegación espera a que el worker se inicie antes de que comience la solicitud de red. Diseña navigation preload para navegadores no compatibles mientras evitas solicitudes duplicadas, escrituras de caché obsoletas y carreras de respuesta.

Lo que evalúa el entrevistador

Navigation preload es una solicitud de navegación iniciada por el navegador que se ejecuta mientras el Service Worker se inicia; no es ni precaching ni link rel=preload para recursos arbitrarios. Cubre cómo habilitarlo durante activate, leer preloadResponse en fetch, la política de red frente a caché, el encabezado Service-Worker-Navigation-Preload, el fallback por tiempo de espera y errores, y la medición.

Preguntas aclaratorias para hacer primero

Destino de la página y la caché

Aclara si la navegación devuelve HTML renderizado en el servidor (SSR), un shell de SPA o una página sin conexión; qué rutas se pueden almacenar en caché; y si los datos específicos del usuario deben omitir las cachés compartidas. Las respuestas personalizadas no deben escribirse en una caché pública.

Ciclo de vida y compatibilidad del navegador

Confirma el registro, la actualización, el alcance de control y la compatibilidad de los navegadores de destino para navigationPreload. No se puede asumir que una primera navegación no controlada pase a través del worker actual.

Política de red y consistencia

Elige el comportamiento network-first, cache-first o stale-while-revalidate y define la respuesta sin conexión. Decide cómo el servidor lee el encabezado de preload sin alterar accidentalmente las claves de caché.

Estructura de respuesta de 30 segundos

“Detecta la compatibilidad de características y habilita navigation preload en el evento activate del Service Worker. El navegador inicia la solicitud de navegación mientras el worker se inicia; el manejador fetch primero espera a event.preloadResponse, luego verifica la caché o llama a fetch solo cuando no existe una respuesta de preload utilizable. Acepta una respuesta únicamente cuando la URL, la identidad y la política de caché coincidan. Compara compatibilidad, tiempo de inicio, TTFB, aciertos de caché, solicitudes duplicadas y errores de fallback antes y después del despliegue.”

Respuesta detallada paso a paso

Paso 1: Habilitarlo durante activate

Tras verificar registration.navigationPreload, llama a enable() dentro de waitUntil de activate para que la configuración se complete antes de que el nuevo worker se considere listo. setHeaderValue() puede agregar contexto, pero el valor no debe contener estado privado o que no sea almacenable en caché.

Paso 2: Consumir preloadResponse en fetch

Lee event.preloadResponse únicamente para solicitudes de navegación. Puede resolverse en un Response o en undefined. Da prioridad a una respuesta de preload válida; de lo contrario, sigue la política de caché o de fetch ordinaria. No inicies una segunda solicitud de red antes de decidir si la promesa de preload ha producido un resultado utilizable.

Paso 3: Definir los límites de caché e identidad

El HTML de SSR que contiene datos de identidad, geografía o experimentos debe respetar las claves de caché y los encabezados de respuesta existentes. No lo coloques incondicionalmente en Cache Storage. Un shell estático puede ser cache-first; una página personalizada puede ser network-first, probando explícitamente el comportamiento de Cookie, Authorization y Vary.

Paso 4: Manejar el encabezado y el enrutamiento del servidor

El servidor puede inspeccionar Service-Worker-Navigation-Preload para reconocer la solicitud paralela y omitir trabajo costoso o usar una caché dedicada. Los proxies y las CDN necesitan una regla explícita para reenviar, ignorar o aplicar Vary a ese encabezado de modo que no genere un uso compartido de caché entre distintos usuarios.

Paso 5: Manejar carreras, tiempos de espera y errores

Si el preload falla, se agota el tiempo de espera o devuelve un estado inadecuado, recurre a la caché o al fetch ordinario según la política establecida. El cuerpo de un Response suele ser de un solo uso; utiliza clone() cuando se requieran dos consumidores y delimita la cancelación y el tiempo de espera. Intenta mostrar una página sin conexión tras un error de red, pero no ocultes un error real del servidor.

Paso 6: Degradar y actualizar de forma segura

Los navegadores no compatibles continúan con el fetch ordinario del Service Worker; los navegadores sin soporte para Service Worker utilizan la red. Durante las actualizaciones del worker, preserva el protocolo de caché anterior y pospón la eliminación hasta que el nuevo worker esté listo para usarse, evitando interrupciones durante la activación.

Paso 7: Medir el rendimiento real y la corrección

Compara inicios en frío y en caliente, redes lentas, modo sin conexión, primeras visitas no controladas y actualizaciones del worker. Registra el tiempo de navegación a respuesta, TTFB, inicio del worker, aciertos de preload, aciertos de caché, solicitudes duplicadas y errores de fallback. Verifica el aislamiento de identidad y el comportamiento del navegador, no solo el tiempo de carga promedio.

Ejemplo de respuesta de alta calidad

Detectaría las características y habilitaría navigation preload en activate, para luego esperar a preloadResponse primero en el manejador fetch de navegación. Solo cuando esté ausente o no sea adecuado, el manejador recurriría a la caché o al fetch ordinario. La política de caché debe separar los shells estáticos del HTML de SSR personalizado, y el servidor puede utilizar el encabezado de preload sin alterar el aislamiento de caché. Los navegadores no compatibles conservan el comportamiento de fetch ordinario. Probaría inicios en frío, redes lentas, modo sin conexión, visitas no controladas, actualizaciones y conteos de solicitudes duplicadas mientras comparo el TTFB y el tiempo de inicio.

Errores comunes

  • Error: Tratar navigation preload como precaching de recursos estáticos. → Por qué falla: Está orientado a la navegación y se ejecuta junto con el inicio del worker. → Solución: Consumir preloadResponse en el manejador fetch.
  • Error: Iniciar un fetch incondicional cuando preload no tiene un resultado inmediato. → Por qué falla: Puede duplicar solicitudes y efectos secundarios. → Solución: Definir el orden de la promesa, la caché y el fetch.
  • Error: Escribir HTML personalizado en un Cache Storage compartido. → Por qué falla: Se ignoran los límites de Cookie, Authorization o Vary. → Solución: Utilizar una política network-first consciente de la identidad.
  • Error: Comparar solo el tiempo de carga promedio. → Por qué falla: Los inicios en frío, las visitas no controladas y las solicitudes duplicadas desaparecen en el promedio. → Solución: Rastrear TTFB, inicio, aciertos y errores por cohorte.

Preguntas de seguimiento y respuestas

Pregunta de seguimiento 1: ¿Por qué no usar link preload directamente?

link rel=preload se declara en la página y está orientado a recursos. Navigation preload es una solicitud del navegador para la navegación que se ejecuta durante el inicio del Service Worker; su ciclo de vida y su API de consumo son diferentes.

Pregunta de seguimiento 2: ¿Por qué preloadResponse puede ser undefined?

Es posible que el navegador no lo admita, que la solicitud no sea una navegación, que el preload esté deshabilitado o que la solicitud de red falle antes del evento del worker. Trata undefined como una bifurcación normal.

Pregunta de seguimiento 3: ¿Cómo se evita leer el cuerpo de un Response dos veces?

El cuerpo de un Response normalmente es de un solo uso. Llama a clone() cuando tanto la página como la caché lo necesiten, y maneja los errores y la cancelación en ambos consumidores.

Pregunta de seguimiento 4: ¿Por qué la primera visita aún podría no mostrar ninguna mejora de velocidad?

Una página no controlada no enruta la navegación a través del worker actual, y el registro, la instalación y la activación toman tiempo. Mide las primeras visitas no controladas por separado en lugar de clasificarlas como fallos de preload.

Fuentes públicas

Preguntas relacionadas