Cómo los web workers y los service workers pueden mejorar el rendimiento de tu sitio y cuándo usar un web worker en lugar de un service worker
En esta descripción general, se explica cómo los trabajadores web y los service workers pueden mejorar el rendimiento de tu sitio web y cuándo usar un trabajador web en lugar de un service worker. Consulta el resto de esta serie para conocer patrones específicos de comunicación entre ventanas y service workers.
Cómo los trabajadores pueden mejorar tu sitio web
El navegador usa un solo subproceso (el subproceso principal) para ejecutar todo el código JavaScript en una página web, así como para realizar tareas como renderizar la página y realizar la recolección de elementos no utilizados. Ejecutar código de JavaScript excesivo puede bloquear el subproceso principal, lo que retrasa la realización de estas tareas por parte del navegador y genera una experiencia del usuario deficiente.
En el desarrollo de aplicaciones para iOS y Android, un patrón común para garantizar que el subproceso principal de la app permanezca libre para responder a los eventos del usuario es descargar las operaciones en subprocesos adicionales. De hecho, en las versiones más recientes de Android, bloquear el subproceso principal durante demasiado tiempo provoca que la app falle.
En la Web, JavaScript se diseñó en torno al concepto de un solo subproceso y carece de las capacidades necesarias para implementar un modelo de varios subprocesos como el que tienen las apps, como la memoria compartida.
A pesar de estas limitaciones, se puede lograr un patrón similar en la Web usando workers para ejecutar secuencias de comandos en subprocesos en segundo plano, lo que les permite realizar tareas sin interferir con el subproceso principal. Los trabajadores son un permiso de JavaScript completo que se ejecuta en un subproceso independiente, sin memoria compartida.
En esta publicación, aprenderás sobre dos tipos diferentes de trabajadores (los trabajadores web y los trabajadores de servicio), sus similitudes y diferencias, y los patrones más comunes para usarlos en sitios web de producción.
Web workers y service workers
Similitudes
Los web workers y los service workers son dos tipos de workers disponibles para los sitios web. Tienen algunos aspectos en común:
- Ambos se ejecutan en un subproceso secundario, lo que permite que el código JavaScript se ejecute sin bloquear el subproceso principal ni la interfaz de usuario.
- No tienen acceso a los objetos
WindowniDocument, por lo que no pueden interactuar con el DOM directamente y tienen acceso limitado a las APIs del navegador.
Diferencias
Se podría pensar que la mayoría de las cosas que se pueden delegar a un trabajador web se pueden hacer en un service worker y viceversa, pero hay diferencias importantes entre ellos:
- A diferencia de los trabajadores web, los service workers te permiten interceptar solicitudes de red (a través del evento
fetch) y escuchar eventos de la API de Push en segundo plano (a través del eventopush). - Una página puede generar varios trabajadores web, pero un solo service worker controla todas las pestañas activas en el alcance con el que se registró.
- La vida útil del Web Worker está estrechamente vinculada a la pestaña a la que pertenece, mientras que el ciclo de vida del Service Worker es independiente de ella. Por ese motivo, cerrar la pestaña en la que se ejecuta un trabajador web lo finalizará, mientras que un service worker puede seguir ejecutándose en segundo plano, incluso cuando el sitio no tiene pestañas activas abiertas.
Casos de uso
Las diferencias entre ambos tipos de trabajadores sugieren en qué situaciones se podría usar uno u otro:
Los casos de uso de los trabajadores web se relacionan más comúnmente con la descarga de trabajo (como cálculos pesados) a un subproceso secundario para evitar el bloqueo de la IU.
- Ejemplo: El equipo que creó el videojuego PROXX quería dejar el subproceso principal lo más libre posible para encargarse de las entradas y animaciones del usuario. Para lograrlo, usaron trabajadores web para ejecutar la lógica del juego y el mantenimiento del estado en un subproceso separado.
Las tareas de los service workers suelen estar más relacionadas con actuar como un proxy de red, controlar tareas en segundo plano y realizar acciones como el almacenamiento en caché y el funcionamiento sin conexión.
Ejemplo: En una PWA de podcasts, es posible que quieras permitir que los usuarios descarguen episodios completos para escucharlos sin conexión. Para ello, se puede usar un service worker y, en particular, la API de Background Fetch. De esa manera, si el usuario cierra la pestaña mientras se descarga el episodio, la tarea no se interrumpirá.
Herramientas y bibliotecas
La comunicación entre ventanas y trabajadores se puede implementar con diferentes APIs de nivel inferior. Afortunadamente, existen bibliotecas que abstraen este proceso y se encargan de los casos de uso más comunes. En esta sección, abordaremos dos de ellas que se encargan de la comunicación de la ventana con los trabajadores web y los trabajadores de servicio, respectivamente: Comlink y Workbox.
Comlink
Comlink es una pequeña biblioteca de RPC (1.6 KB) que se encarga de muchos detalles subyacentes cuando se crean sitios web que usan Web Workers. Se usó en sitios web como PROXX y Squoosh. Puedes encontrar un resumen de sus motivaciones y muestras de código aquí.
Workbox
Workbox es una biblioteca popular para compilar sitios web
que usan service workers. Empaqueta un conjunto de prácticas recomendadas sobre aspectos como el almacenamiento en caché, la sincronización en segundo plano,
sin conexión, etc. El módulo workbox-window proporciona una
forma conveniente de intercambiar mensajes entre el service worker y la página.
Próximos pasos
El resto de esta serie se enfoca en los patrones para la comunicación entre ventanas y service workers:
- Guía de almacenamiento en caché imperativo: Llama a un service worker desde la página para almacenar en caché los recursos con anticipación (p.ej., en situaciones de carga previa).
- Actualizaciones de transmisión: Se llama a la página desde el service worker para informar sobre actualizaciones importantes (p.ej., hay una nueva versión del sitio web disponible).
- Comunicación bidireccional: Delegar una tarea a un service worker (p.ej., una descarga pesada) y mantener la página informada sobre el progreso.
Para conocer los patrones de comunicación de ventanas y trabajadores web, consulta Usa trabajadores web para ejecutar JavaScript fuera del subproceso principal del navegador.