Introducción a los Web Workers

Aunque las tecnologías Javascript han avanzado a pasos agigantados, aún nos encontramos con páginas web que bloquean las interacciones del usuario al estar ejecutando operaciones pesadas.
Para evitar esto, HTML5 nos proporciona una manera sencilla de implementar multithreading en Javascript: Los Web Workers.
Definición
Un Web Worker es un script que se ejecuta en segundo plano, sin afectar o bloquear el desempeño de nuestra página web.
Hay dos clases de workers: dedicados y compartidos.
· Los workers dedicados, una vez creados, están vinculados a su creador, pero utilizan puertos de mensajes para comunicarse desde un worker dedicado a varios contextos o workers.
· Los workers compartidos, por otro lado, son nombrados; una vez creados, cualquier script que se ejecute en el mismo origen puede obtener una referencia a ese worker y comunicarse con él.
Hay que tener en cuenta que los workers trabajan dentro de un contexto global diferente de la ventana actual, y como se encuentran en archivos externos, no tienen acceso a los objetos document, window o parent.
Cómo utilizarlos
1.- Es una buena práctica, antes de utilizar un web worker, verificar que sea soportado por el browser, utilizando el siguiente código
2.- Un web worker se crea a partir de un archivo externo de Javascript, donde pondremos la función que ejecutará el web worker. Si no deseamos crear otro archivo, podemos crear una función f, como string y después crear un objeto tipo archivo
Supongamos que vamos a implementar un Contador. Podemos crear un archivo ‘cont.js’ con el siguiente código
Lo que es importante notar en esta función, es la instrucción postMessage, la cual será la encargada de devolver la información del worker a la página HTML.
3.- Ya que tenemos el código que ejecutará nuestro worker, podemos proceder a crearlo, de la siguiente manera:
Y entonces, mediante un listener, podemos enviar y recibir mensajes del worker
Cuando el worker publica un mensaje, se ejecuta el código dentro del listener de eventos. Los datos del worker se almacenan en event.data.
También podemos escuchar los errores con la siguiente instrucción:
4.- Por último, al igual que los threads, no debemos olvidar finalizar el worker, ya que este continuará escuchando mensajes (incluso después de finalizado el script externo) hasta que se termine.
Para finalizar un worker y liberar los recursos, utilizaremos el método terminate ():
Si quisiéramos reutilizar la variable work una vez que hemos terminado el worker, podemos asignarle undefined, y de este modo podremos crear un nuevo worker
Puedes encontrar un excelente ejemplo en el sito de w3schools
https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_webworker
El esquema de trabajo
Como pueden ver, el esquema es muy sencillo: el worker tiene un detector de eventos, que es invocado por la función worker.postMessage() en el script principal. El worker procesa el mensaje y envía los datos al script principal mediante su método self.postMessage(). El script principal también tiene un detector de eventos, el worker.onmessage, o el worker.onerror, que llaman a una función con el mensaje para procesar los datos.

Los datos
Los datos pasados entre la página principal y los workers se copian, no se comparten. Los objetos se serializan al pasarse al worker, y posteriormente, se de-serializados en el otro extremo. La página y el workers no comparten la misma instancia, por lo que el resultado final es que se crea un duplicado en cada extremo. La mayoría de los navegadores implementan esta función como clonación estructurada.
El algoritmo clonado estructurado es un algoritmo definido por la especificación HTML5. Permite pasar tipos más complejos dentro y fuera de los trabajadores como RegExp, File, imageData, Blob, ArrayBuffer y objetos JSON. Sin embargo, no puede clonar objetos de error o función.
Si desea enviar datos de gran tamaño, tiene otra opción, pasar datos mediante objetos transferibles, los cuales se pasan de un contexto a otro sin operaciones de copiado Cambiar el contexto significa que los datos del contexto de llamada ya no están disponibles una vez transferidos al nuevo contexto y viceversa.
Conclusiones
Aunque que no todos los browsers soportan los workers, las versiones más recientes si lo hacen y son una excelente alternativa para lidiar con tareas pesadas que tengan que ejecutarse sin bloquear las páginas a la interacción con el usuario. A continuación está una tabla con los browsers y la versión mas antigua de ellos que permite el uso de workers.

Bibliografia
The Basics of Web Workers
https://www.html5rocks.com/en/tutorials/workers/basics/
Web workers
https://w3c.github.io/workers/
JS Workout. Web workers and responsiveness
http://js-workout.tompascall.com/web-workers-and-responsiveness/

