Responde a las solicitudes de navegación sin esperar en la red con un service worker.
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 lleva a una URL nueva. Aquí es donde los service workers tienen su mayor impacto en el rendimiento: si usas un service worker para responder a las solicitudes de navegación sin esperar a la red, puedes asegurarte de que las navegaciones sean rápidas y confiables, además de resilientes cuando la red no esté disponible. Esta es la mayor mejora de rendimiento que se obtiene de un service worker, en comparación con lo que es posible con el almacenamiento en caché HTTP.
Como se detalla en la guía Identifica los recursos cargados desde la red, una solicitud de navegación es la primera de muchas solicitudes que se pueden realizar en la "cascada" del 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 recursos secundarios, como imágenes, secuencias de comandos y estilos.
Dentro del controlador de eventos fetch de un service worker, puedes determinar si una solicitud es una navegación verificando la propiedad request.mode en el FetchEvent. Si se establece en '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, deben satisfacerse 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, sea (razonablemente) reciente. Desafortunadamente, consultar 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á confiablemente rápido.
Diferentes enfoques para las arquitecturas
Determinar 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 casos, los siguientes lineamientos generales deberían ayudarte a decidir qué enfoque es el 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 simplemente almacenar en caché todos esos archivos HTML y responder a las solicitudes de navegación con el HTML almacenado en caché adecuado.
Con el almacenamiento previo en caché, puedes almacenar en caché el código HTML con anticipación, en cuanto se instale el service worker, y actualizar el código HTML almacenado en caché cada vez que vuelvas a compilar tu sitio y a implementar el service worker.
Como alternativa, si prefieres evitar el almacenamiento previo en caché de todo tu HTML, tal vez porque los usuarios tienden a navegar solo a un subconjunto de URLs en tu sitio, puedes usar una estrategia de almacenamiento en caché del entorno de ejecución stale-while-revalidate. Sin embargo, ten cuidado con este enfoque, ya que cada documento HTML individual se almacena en caché y se actualiza por separado. El uso del almacenamiento en caché del entorno de ejecución para HTML es más apropiado si tienes una pequeña cantidad de URLs que el mismo conjunto de usuarios vuelve a visitar con frecuencia y si te sientes cómodo con que esas URLs se vuelvan a validar de forma independiente entre sí.
Apps de una sola página
Las aplicaciones web modernas suelen usar una arquitectura de una sola página. En este caso, el código JavaScript del cliente modifica el 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 puedes seguir para entregar la navegación inicial desde la caché: la shell de la aplicación. En este modelo, tu service worker responde a las solicitudes de navegación devolviendo 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 constar, tal vez, de un indicador de carga genérico o un contenido de esqueleto. Una vez que el navegador haya cargado este HTML desde la caché, el JavaScript del cliente existente tomará el control y renderizará el contenido HTML correcto para la URL de la solicitud de navegación original.
Workbox proporciona las herramientas que necesitas para implementar este enfoque. El navigateFallback
option
te permite especificar qué documento HTML usar como shell de la app, junto con una lista opcional de elementos permitidos y
denegados 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 decenas 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 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 los entornos del servidor y del service worker 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 se encuentra en esa categoría y deseas explorar un enfoque para trasladar la generación de HTML fuera de la red y a tu service worker, la guía en Más allá de las SPA: arquitecturas alternativas para tu PWA puede ayudarte a comenzar.
Todas las demás
Si no puedes responder a las solicitudes de navegación con HTML almacenado en caché, debes tomar medidas para asegurarte de que
agregar un service worker a tu sitio (para controlar otras solicitudes que no sean de HTML) no termine ralentizando
tus navegaciones. Iniciar el service worker sin usarlo para responder a una solicitud de navegación
generará una pequeña cantidad de latencia (como se explica en Cómo compilar apps más rápidas y resilientes
con service workers). Puedes mitigar esta sobrecarga habilitando
una función llamada precarga
de navegación y, luego, usando la
respuesta
de la red
que se precargó dentro de tu controlador de eventos fetch.
Workbox proporciona una biblioteca auxiliar que detecta si se admite la precarga de navegación y, de ser así, simplifica el proceso de indicarle al service worker que use la respuesta de red.