Expectativas en torno a la implementación de service worker

La implementación de un service worker puede cambiar los comportamientos de un sitio web de forma inesperada. Debido a que Workbox facilita la escritura y la implementación de un service worker, puede ser más fácil pasar por alto algunos de los efectos que tiene un service worker en un sitio web una vez implementado.

Esto no significa que el uso de Workbox produzca malos resultados, solo que la practicidad que ofrece puede facilitar algunas dificultades si no se sabe lo que implica la implementación de un service worker.

Errores del almacenamiento previo en caché

El almacenamiento previo en caché se explicó anteriormente en estos documentos sin abordar por completo cómo la práctica puede ser contraproducente. Es posible que encuentres problemas si aplicas el almacenamiento previo en caché a demasiados recursos o si el service worker se registra antes de que la página tenga la oportunidad de terminar de cargar recursos críticos.

Dado que el comportamiento predeterminado de workbox-webpack-plugin es indicarle al service worker que almacene previamente en caché los recursos generados automáticamente, esto puede ser problemático de una manera fácil de pasar por alto, ya que la barrera para la adopción es baja.

Resultado de la terminal.
Salida de la terminal de workbox-webpack-plugin. En este ejemplo, se almacena en caché 14 recursos del proyecto actual con un total de 352 kilobytes de forma predeterminada.

Cuando un service worker almacena previamente en caché los recursos durante la instalación, se inician simultáneamente una o más solicitudes de red. Esto puede ser un problema para la experiencia del usuario si no se aplica el tiempo adecuado. Incluso si el momento es preciso, se pueden desperdiciar datos si la cantidad de elementos prealmacenados en caché no está limitada de alguna manera.

Todo depende del momento

Si un service worker almacena contenido en caché por adelantado, la hora en la que se registró es importante. A menudo, los service workers se registran con elementos <script> intercalados. Esto significa que los analizadores de HTML pueden descubrir el código de registro del service worker antes de que se hayan cargado los recursos críticos de la página.

Esto es un problema. Idealmente, el service worker debe ser neutral en cuanto al rendimiento en el peor de los casos, y no empeorar el rendimiento. Dale un favor a los usuarios y registra un service worker cuando se active el evento load de la página. De esta manera, se reduce la posibilidad de que el almacenamiento previo en caché interfiera en la carga de los elementos críticos de una página, lo que, a su vez, significa que la página puede volverse interactiva más rápido sin tener que lidiar con las solicitudes de red por recursos que tal vez no se necesiten hasta más adelante.

Ten en cuenta el uso de datos

Más allá del tiempo, el almacenamiento previo en caché implica despachar solicitudes de red. Si no se selecciona cuidadosamente un manifiesto de elementos que se almacenan en caché, podría generar un desperdicio.

El desperdicio de datos es una posible compensación del almacenamiento previo en caché, pero no todos tienen acceso a una Internet rápida o incluso planes de datos ilimitados. Cuando guardes el almacenamiento previo en caché, considera quitar los recursos particularmente grandes y confía en el almacenamiento en caché del entorno de ejecución para capturarlos, en lugar de hacer suposiciones costosas.

El inicio del service worker puede retrasar las solicitudes de red

Los service workers se ejecutan en un proceso independiente del resto del código de un sitio web. Este proceso se inicia y se detiene con frecuencia. Cuando un service worker necesita controlar un evento de recuperación después de estar inactivo, el navegador primero debe dedicar tiempo a iniciarlo. Esta sobrecarga adicional antes de que se pueda controlar una solicitud es pequeña en comparación con el beneficio de entregar una respuesta desde la caché en lugar de la red.

Cuando se utilizan estrategias que no pueden entregar desde la caché y tienen que ir a la red (especialmente cuando se manejan solicitudes de navegación), el tiempo de inicio siempre agrega demora. Según las capacidades del dispositivo o la presión de la CPU, una solicitud de navegación puede experimentar un retraso notable debido a los inicios lentos de los service worker. Si se implementa un service worker sin tener en cuenta este retraso, los usuarios podrían experimentar un impacto no intencional en el rendimiento.

Este problema se resolvió con la precarga de Navigation, pero todavía no es compatible con todos los navegadores. Sin embargo, su uso vale la pena considerarlo, y se trata más adelante en esta documentación.

Las estrategias centradas en la caché pueden tener consecuencias negativas

Las estrategias de almacenamiento en caché que consultan primero la caché (o solo consultan la caché) son excelentes para el rendimiento y el acceso sin conexión. Sin embargo, suelen causar problemas en algunos casos específicos.

Almacenamiento en caché del entorno de ejecución de elementos estáticos sin control de versiones

Por lo general, los agrupadores crean versiones de elementos estáticos con un hash basado en el contenido en el nombre del archivo (por ejemplo, styles.a4edf38c.css). En los service workers que usan estrategias de almacenamiento en caché que consultan primero la caché para recursos estáticos y usan una estrategia centrada en la red para el lenguaje de marcado de la página, no deberían producirse problemas de almacenamiento en caché, ya que se hace referencia a los elementos actualizados en el lenguaje de marcado que siempre se recupera de la red.

Los problemas surgen en situaciones en las que los elementos estáticos sin versiones se almacenan en caché durante el tiempo de ejecución usando estas estrategias. Si app.js proporciona la funcionalidad de un sitio web y se usa una estrategia de entorno de ejecución que prioriza la caché, luego se actualiza app.js sin que se produzca ningún cambio en el nombre del archivo, la versión inicialmente almacenada en caché se seguirá entregando desde la caché en lugar de actualizarse.

La solución es usar una estrategia que consulte a la red en busca de actualizaciones, como la priorización de la red o la inactividad durante la revalidación. Como alternativa, las herramientas de compilación pueden generar un manifiesto de almacenamiento previo en caché para esos elementos, ya que la lógica de almacenamiento previo en caché de Workbox los mantendrá actualizados.

En cualquier caso, considera controlar las versiones de los recursos estáticos, ya sea mediante un hash en el nombre del recurso o en la cadena de consulta. Esto evitará problemas relacionados con los elementos inactivos en los service workers que usan estrategias de tiempo de ejecución en las que se prioriza la caché para los recursos estáticos.

Ten en cuenta las cuotas de almacenamiento

Es común lanzar actualizaciones del service worker de vez en cuando y, cuando se lanzan las actualizaciones, las cachés antiguas con nombres vencidos generalmente se reducen durante la activación del nuevo service worker.

Sin embargo, algunas iteraciones del service worker son de larga duración, o es posible que los nombres de la caché no se actualicen con las actualizaciones nuevas. Cuando esto sucede, los recursos estáticos antiguos pueden acumularse en cachés a medida que se lanzan sus actualizaciones. Los navegadores establecen cuotas de almacenamiento, y los límites pueden variar. Ese es un buen motivo para tenerlo en cuenta.

Workbox mitiga correctamente estos problemas, pero aún se pueden exceder las cuotas de almacenamiento. Puedes lograr un control más preciso de las memorias caché con el módulo de vencimiento del cuadro de trabajo.

No desespere.

La implementación de un service worker no es algo sencillo. Sin embargo, no debería ser una proeza aterradora con un poco de planificación y mindfulness de lo que implica implementar un service worker con Workbox. A medida que continúes, esta documentación te ayudará a abordar estas inquietudes con cuidado y confianza.