Responde a las solicitudes de navegación sin esperar en la red con un trabajador de servicio.
Las solicitudes de navegación son solicitudes de documentos HTML que realiza tu navegador cada vez que ingresas una URL nueva en la barra de navegación o sigues un vínculo en una página que te dirige a una URL nueva. Aquí es donde los trabajadores de servicio tienen el mayor impacto en el rendimiento: si usas un trabajador de servicio para responder solicitudes de navegación sin esperar a la red, puedes asegurarte de que las navegaciones sean rápidas y confiables, además de ser resilientes cuando la red no está disponible. Esta es la mejora de rendimiento más significativa que se obtiene de un trabajador de servicio, en comparación con lo que es posible con la caché HTTP.
Como se detalla en la guía Cómo identificar los recursos cargados desde la red, una solicitud de navegación es la primera de varias solicitudes que se realizan en la cascada de tráfico de red. El código HTML que cargas a través de una solicitud de navegación inicia el flujo de todas las demás solicitudes de subrecursos, como imágenes, secuencias de comandos y estilos.
Dentro del controlador de eventos fetch
de un trabajador de servicio, puedes determinar si una solicitud es una navegación verificando la propiedad request.mode
en FetchEvent
. Si está configurado como 'navigate'
, es una solicitud de navegación.
Como regla general, no uses Cache-Control headers
de larga duración para almacenar en caché
la respuesta HTML de una solicitud de navegación. Por lo general, se deben satisfacer a través de la red, con Cache-Control: no-cache
, para garantizar que el HTML, junto con la cadena de solicitudes de red posteriores, esté (razonablemente) actualizado. Lamentablemente, ir contra la red cada vez que el usuario navega a una página nueva significa que cada navegación podría ser lenta. Como mínimo, significa que no será confiable.
Diferentes enfoques para las arquitecturas
Descubrir cómo responder a las solicitudes de navegación y, al mismo tiempo, evitar la red puede ser complicado. El enfoque correcto depende en gran medida de la arquitectura de tu sitio web y de la cantidad de URLs únicas a las que los usuarios podrían navegar.
Si bien no existe una solución única para todos, los siguientes lineamientos generales deberían ayudarte a decidir cuál es el enfoque más viable.
Sitios estáticos pequeños
Si tu app web consta de una cantidad relativamente pequeña (por ejemplo, un par de docenas) de URLs únicas y cada una de esas URLs corresponde a un archivo HTML estático diferente, un enfoque viable es almacenar en caché todos esos archivos HTML y responder a las solicitudes de navegación con el HTML almacenado en caché adecuado.
Con la caché previa, puedes almacenar en caché el código HTML con anticipación, en cuanto se instale el trabajador de servicio, y actualizar el código HTML almacenado en caché cada vez que vuelvas a compilar tu sitio y a implementar el trabajador de servicio.
Como alternativa, si prefieres evitar la caché previa de todo tu HTML, quizás porque los usuarios suelen navegar solo a un subconjunto de URLs en tu sitio, puedes usar una estrategia de almacenamiento en caché del tiempo de ejecución inactivo durante la validación. Sin embargo, ten cuidado con este enfoque, ya que cada documento HTML individual se almacena en caché y se actualiza por separado. El uso de la caché del tiempo de ejecución para HTML es más adecuado si tienes una pequeña cantidad de URLs que el mismo conjunto de usuarios vuelve a visitar con frecuencia y si te sientes a gusto con que esas URLs se vuelvan a validar independientemente una de la otra.
Apps de una sola página
Las aplicaciones web modernas suelen usar una arquitectura de una sola página. En él, JavaScript del cliente modifica el código HTML en respuesta a las acciones del usuario. Este modelo usa la API de History para modificar la URL actual a medida que el usuario interactúa con la app web, lo que genera una navegación "simulada". Si bien las navegaciones posteriores pueden ser "falsas", la navegación inicial es real y sigue siendo importante asegurarse de que no esté bloqueada en la red.
Afortunadamente, si usas la arquitectura de una sola página, hay un patrón sencillo que se puede seguir para entregar la navegación inicial desde la caché: el shell de la aplicación. En este modelo, el trabajador de servicio responde a las solicitudes de navegación mostrando el mismo archivo HTML único que ya se almacenó en caché, independientemente de la URL que se solicite. Este HTML debe ser básico y consistir, quizás, en un indicador de carga genérico o en contenido de esqueleto. Una vez que el navegador carga este código HTML desde la caché, se apodera de tu código JavaScript del cliente existente y renderiza el contenido HTML correcto para la URL de la solicitud de navegación original.
Workbox proporciona las herramientas que necesitas para implementar este enfoque. navigateFallback
option
te permite especificar qué documento HTML usar como shell de la app, junto con una lista opcional de elementos permitidos y rechazados para limitar este comportamiento a un subconjunto de tus URLs.
Apps de varias páginas
Si tu servidor web genera el código HTML de tu sitio de forma dinámica o si tienes más de unas pocas docenas de páginas únicas, es mucho más difícil evitar la red cuando se manejan solicitudes de navegación. Es probable que se apliquen a ti los consejos de Todo lo demás.
Sin embargo, para un subconjunto determinado de apps de varias páginas, es posible que puedas implementar un service worker que replique por completo la lógica que se usa en tu servidor web para generar HTML. Esto funciona mejor si puedes compartir información de enrutamiento y plantillas entre el servidor y los entornos de trabajadores del servicio y, en particular, si tu servidor web usa JavaScript (sin depender de funciones específicas de Node.js, como el acceso al sistema de archivos).
Si tu servidor web pertenece a esa categoría y deseas explorar un enfoque para trasladar la generación de HTML de la red a tu trabajador de servicio, la guía de Más allá de las SPA: Arquitecturas alternativas para tu PWA puede ayudarte a comenzar.
Todas las demás
Si no puedes responder solicitudes de navegación con HTML almacenado en caché, debes tomar medidas para asegurarte de que agregar un trabajador de servicio a tu sitio (para controlar otras solicitudes que no sean HTML) no ralentice tus navegaciones. Si inicias el service worker sin usarlo para responder a una solicitud de navegación, se introducirá una pequeña cantidad de latencia (como se explica en Cómo compilar apps más rápidas y resilientes con Service Worker). Puedes mitigar esta sobrecarga habilitando una función llamada carga previa de navegación y, luego, usando la respuesta de red que se cargó previamente dentro de tu controlador de eventos fetch
.
Workbox proporciona una biblioteca de ayuda que detecta si se admite la carga previa de navegación y, de ser así, simplifica el proceso de indicarle a tu trabajador de servicio que use la respuesta de red.
Foto de Aaron Burden en Unsplash