05 diciembre, 2008

Concurrencia en el navegador

Este miércoles, Andrea Giammarchi publicaba un método que se aprovechaba de las clausuras para crear scripts que no se bloqueen al cargar la página. Lo cierto es que el uso de las librerías y del lenguaje Javascript en general ha aumentado lo suficiente como para que se estén alcanzando todos los límites que durante años han sido suficientes. Las aplicaciones web no dejan de crecer en funcionalidad y prueba de que el rendimiento empieza a resentirse es la aparición de nuevos motores mucho más optimizados que están dejando sin argumentos a quienes decían despectivamente que "ese es un lenguaje de juguete".

Google que ha hecho un excelente trabajo con Gears para suplir las carencias de los navegadores, ya incluyó su WorkersPool con la idea de lanzar hilos de código que se ejecuten en segundo plano de forma que no bloqueen el navegador y ofrezcan al visitante una sensación de lentitud no deseada.

Hoy es notícia que la próxima versión de Firefox 3.1 incluirá una nueva especificación (parte 1, parte 2) acordada con Apple (Safari) y Google (que tendrá que variar la de Gears) que facilitará mucho la creación de aplicaciones web receptivas:

var worker = new Worker("workerScript.js");

Tal y como se explica aquí, ese archivo workerScript.js podrá hacer prácticamente cualquier cosa, incluyendo peticiones Ajax XMLHttpRequest, importar scripts adicionales con importScripts, lanzar otros workers, establecer intervalos o tiempos de espera, y pasar mensajes entre ellos con JSON.

El siguiente ejemplo muestra el cálculo de la función de Fibonacci mediante un hilo de forma que no bloquea la página que está visualizando el visitante y que es la que espera el resultado final:

fibonacci.js


var results = [];

function resultReceiver(event) {
  results.push(parseInt(event.data));
  if (results.length == 2) {
    postMessage(results[0] + results[1]);
  }
}

function errorReceiver(event) {
  throw event.data;
}

onmessage = function(event) {
  var n = parseInt(event.data);

  if (n == 0 || n == 1) {
    postMessage(n);
    return;
  }

  for (var i = 1; i <= 2; i++) {
    var worker = new Worker("fibonacci.js");
    worker.onmessage = resultReceiver;
    worker.onerror = errorReceiver;
    worker.postMessage(n - i);
  }
 }

HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <title>Test threads fibonacci</title>
  <body>

  <div id="result"></div>

  <script language="javascript">

    var worker = new Worker("fibonacci.js");

    worker.onmessage = function(event) {
      document.getElementById("result").textContent = event.data;
      dump("Got: " + event.data + "\n");
    };

    worker.onerror = function(event) {
      dump("Worker error: " + event.data + "\n");
      throw event.data;
    };

    worker.postMessage("5");

  </script>
  </body>
</html>

Publicar un comentario en la entrada

Últimos links en indiza.com