Hay algunos artículos (por ejemplo 1,2,3) que hacen hincapié en la que probablemente constituya la nueva plataforma web más importante de la década. La combinación de las mejoras y los estándares que rodean a ECMAScript (Javascript) junto con los nuevos motores que han multiplicado en varios factores la velocidad del lenguaje, el interés por AJAX y nuevas formas de comunicación (Comet, Google SPDY, websockets nativos), y los proyectos emergentes que no dejan de aparecer para usar el lenguaje en el lado del servidor, se están uniendo para empujar el desarrollo web basado en Javascript hacia la vanguardia de la tecnología web.
Puede que los entornos corporativos tarden más en aceptar la simplicidad, flexibilidad y del lenguaje, al igual que resisten con XML respecto a JSON o con Java respecto a Ruby o Python, pero es cuestión de tiempo que la fuerza que alberga un lenguaje extremadamente simple y a la vez extremadamente potente salga a flote y por fin se le haga justicia. Recordemos que JS parte con una resistencia adicional y es que muchos programadores, especialmente de Java, mantienen cierto grado de odio hacia el lenguaje, procedente de la falta de distinción entre el lenguaje en sí, que apenas varía entre navegadores, y la patética implementación del DOM en cada navegador.
La capa de presentación ahora en el navegador
Gmail supuso un antes y un después en la tecnología web. Sigue siendo la aplicación modelo, la que demuestra que es posible tener un aplicativo casi tan rápido como el de escritorio. Tradicionalmente, la presentación se ha generado en el servidor escupiendo una secuencia HTML que debería ser interpretada por el navegador. Esto es así porque se tiene un control de la salida desde el punto en el reside la lógica de negocio. Recientemente se ha extendido el paradigma MVC (Modelo-Vista-Controlador) que permite separar de forma lógica estas tres capas de una aplicación de forma que el código pueda crecer fácilmente sin que la mantenibilidad de ésta se resienta. Sin embargo, la forma tradicional de generar ese código HTML a enviar al navegador ha sido mediante templates o lo que es mucho peor: entrelazando código del servidor de aplicaciones con el de presentación hasta alcanzar límites como el siguiente (fuente):<select name="type"> <c:forEach items="${types}" var="type"> <option value="${type.id}" <c:if test="${item.defaultType == type.id}"> selected</c:if>> <c:out value="${type.name}"/> </option> </c:forEach> </select> <input type="button" value="Add <c:out value="${item.name}"/> to cart" onClick="addItem('<c:out value="${item.guid}"/>')"/>Los problemas que esta arquitectura, utilizada ampliamente en la actualidad, presenta son innumerables, entre ellas:
- Mala distribución de la potencia de procesamiento. Prácticamente todo el trabajo lo realiza el servidor, a pesar de que los clientes a los que se sirve la aplicación tienen potentes máquinas que apenas se aprovechan.
- Modelo de programación complicado, ya que toda interacción con el servidor implica una interfície de petición/respuesta, que además genera esperas al usuario.
- Mayor vector de ataque y, por tanto, menor seguridad. Entremezclar lógica de negocio con la presentación supone que el crecimiento de la aplicación genere nuevos puntos débiles en la seguridad por la que ésta puede ser atacada.
- Consumo elevado de memoria en el servidor para mantener estructuras de datos sobre las sesiones abiertas por los usuarios.
- Uso ineficiente de los recursos de conexión al requerir que documentos relativamente extensos en HTML (o sea, poco optimizados para el ancho de banda) sean enviados al navegador para cualquier cambio de estado en la aplicación.
- Complicación a la hora de generar la versión offline de las aplicaciones web. Una capa de presentación generada por el servidor necesita de conexión para ser accesible desde el navegador. Readaptar la aplicación para ello implicará, probablemente, reescribir entera dicha capa a parte de la lógica propia del funcionamiento offline.
- El estándar E4X (ECMAScript for XML) permite definir elementos directamente como variables JavaScript:
var sales = <sales vendor="John"> <item type="peas" price="4" quantity="6"/> <item type="carrot" price="3" quantity="10"/> <item type="chips" price="5" quantity="3"/> </sales>; alert( sales.item.(@type == "carrot").@quantity ); alert( sales.@vendor ); for each( var price in sales..@price ) { alert( price ); }
- JAML permite definir elementos usando una sintaxis muy sencilla basada en llamadas a funciones:
div( h1("Un titulo"), p("Un texto o parrafo cualquiera"), br(), ul( li("Primer item"), li("Segundo item"), li("Tercer item") ) );
- JSONML es una aplicación del formato JSON que puede representar XHTML perfectamente:
[ "ul", { style : "list-style-type:none"}, [ "li", "Primer item"], [ "li", "Segundo item"], [ "li", "Tercer item"], ];
- El Zen-coding es un formato pensado para generar código XHTML rápidamente en un editor de texto, pero más de uno ha adaptado a jQuery o Mootools la misma sintaxis permitiendo, por ejemplo, generar el mismo código XHTML del ejemplo anterior con la cadena
ul>jQuery('ul li:3[innerHTML="item"]').satisfy();
o$('body').zen('ul>li*3>span');
- WebSockets que les permitirá mantener una conexión abierta bi-direccional con el servidor, optimizando así la información transmitida, el tamaño de los datos, el tiempo de respuesta y posibilitando la nuevas aplicaciones web en tiempo real (chats, información de bolsa o juegos multijugador, por ejemplo) y dejando AJaX desfasado ante la llegada, por fin, de Comet.
- WebWorkers que permitirá que las aplicaciones web puedan disponer de un sucedáneo de la programación concurrente en el navegador, de forma que procesos pesados no hagan más lenta la respuesta de la interfície de cara al usuario.
- Web SQL Database para ofrecer el lenguaje SQL en el cliente y posibilitar trabajar offline con una aplicación web.
Javascript en el servidor
Como comentaba al principio, JavaScript está escapando del navegador con una fuerza destacable, sólo achacable a la potencia de un lenguaje bastante viejo que sólo unos pocos han sabido reconocer. No sólo aparece en la capa del servidor de aplicaciones, también lo está haciendo en la base de datos. Dos estándares CommonJS y JSGI están cubriendo rápidamente la falta de acuerdo en un terreno tan cambiante. EL primero define una serie de APIs críticas para construir módulos reutilizables en el entorno del servidor. Por ello cubre facetas como la interacción con la base de datos, el acceso al sistema de archivos, el servidor web o la generación de formatos. El segundo define la forma Javascript con la que interactuar desde el servidor web con las conexiones HTTP, definiendo una representación del protocolo mediante un objeto JSON/Javascript. Entre lo más puntero de la tecnología web en el servidor se encuentra la utilización de bucles asíncronos de eventos para tratar con las conexiones entrantes en lugar de usar hilos del sistema operativo para ello. En las comparaciones entre los servidores NginX y Apache, que siguen precisamente cada una de esas técnicas, se puede ver que no sólo NginX consume mucha menos memoria sino que también es capaz de soportar muchas más conexiones concurrentes. Siguiendo esa misma filosofía han aparecido proyectos como Twisted para Python, EventMachine para Ruby y ahora Node.js para Javascript. Los tres han sido creados de forma que no contienen llamadas bloqueantes como las que se realizan al sistema operativo para leer un archivo. Para ello se basan en un mecanismo que JavaScript ya incorpora de forma natural: las funciones callback que son llamadas cuando el trabajo solicitado ha sido completado, dejando que mientras tanto el sistema siga ejecutando otros procesos del bucle de eventos y, por tanto, incrementando exageradamente el rendimiento. Muchos incorporan un mecanismo llamado promises que permiten escribir código de la forma más parecida al sistema procedimental tradicional (en secuencia) y evitar así romper una misma función como bloque conceptual en varias funciones distintas cada vez que se necesite una llamada bloqueante (acceso a disco, base de datos o nueva conexión). Helma NG es la nueva versión del proyecto activo más antiguo que, siguiendo el estilo MVC ofrecía la posibilidad de usar el motor Rhino de Java y el servidor web Jetty para generar aplicaciones con JS. Pero en relativamente poco tiempo han aparecido muchas más opciones:- Persevere es un servidor de aplicaciones que ofrece una arquitectura REST para intercambiar datos (preferentemente en JSON) con un cliente rico posibilitando así aplicaciones complejas. Así mismo ofrece persistencia de datos, gestión de la seguridad, notificaciones Comet y capacidades avanzadas de comunicación para múltiples plataformas. Con la aparición de nuevas plataformas CommonJS, este proyecto probablemente ofrecerá opciones para instalarse sobre ellos (por ejemplo sobre Node.js).
- Flusspferd es un proyecto que aúna SpiderMonkey (el motor de JS en C++) con una serie de módulos (SQLite,GMP,Zest,Juice,cUrl...) para ofrecer un entorno de ejecución muy rápido aunque está un poco verde.
- En la misma situación se encuentra EJScript, que además añade algunas extensiones de JavaScript que fueron eliminadas del estándar. Su principal baza es el rendimiento que se acerca al de Node.js pero con una décima parte del consumo de memoria de aquel.
- Narwhal es la implementación de CommonJS más avanzada y madura ya que incluye todos sus módulos, ofreciendo soporte completo de entrada/salida, una colección de módulos de librería, un sistema de gestión de paquetes llamado tusk y se ha diseñado para funcionar sobre varias plataformas Javascript.
- node.js está generando una auténtica riada de reacciones en la comunidad web. Básicamente porque mata tres pájaros de un tiro: consigue un rendimiento escandaloso para tratarse de Javascript aunando el motor V8 y su filosofía asíncrona; su tratamiento de bajo nivel de las conexiones permite usarlo como servidor HTTP pero también Comet adelantándose al futuro; y aprovecha el mecanismo de funciones callback al que estamos más que acostumbrados los programadores. Actualmente está muy bien posicionado para coronarse en el rey de los servidores de aplicaciones basados en lenguajes dinámicos. Además se espera que Narwhal funcione sobre Node con las ventajas adicionales de un sólido software orientado totalmente a la gestión segura de datos en el servidor. Como limitaciones: es demasiado inmaduro porque acaba de ser publicado; de momento sólo implementa el sistema de módulos de CommonJS y no el resto de APIs; aún no puede aprovechar los servidores con varios núcleos; no soporta la especificación JSGI.
- appjet.com era un entorno de ejecución de aplicaciones JS basado en Rhino/Java. Por desgracia ha sido comprado por Google y el enlace de descarga del archivo .jar que contenía todo el entorno ya no está accesible.
- Aptana Jaxer también se adelantó en unos meses a su tiempo. Enfocaron el desarrollo en incorporar el motor de renderizado Mozilla Gecko en el lado del servidor y en reutilizar el mismo código en cliente y servidor en un sistema que quizá no resulte demasiado intuitivo para el programador tradicional y que fomenta la generación de la presentación en el servidor. Por desgracia, aunque no ha desaparecido, este proyecto también ha sido relegado por la empresa que lo desarrolla.
Futuro
Con todo ello, es fácil plantearse si sería posible realizar hoy día una aplicación web conociendo únicamente JavaScript. La respuesta obvia es que no, pero ya son muy pocas las piezas que quedan:- Datos. Existen ya servidores de bases de datos que hablan JS como CouchDB con su revolucionario enfoque a la hora de realizar consultas de datos basadas en el sistema MapReduce. También MongoDB ofrece una interfície REST para tratar con sus documentos JSON, el formato de datos propio de Javascript. No es casualidad que ambas pertenezcan al ámbito de la las nuevas bases de datos conocidas como NoSQL, donde el paradigma relacional que se ha demostrado como problemático para la escalabilidad es dejado atrás a favor de otras opciones menos rígidas. Se echa en falta un estándar para definir consultas basadas en el lenguaje Javascript. SQL está muy extendido, pero estoy seguro que se puede hacer lo mismo que CouchDB ofrece con menos complejidad. Quizá al estilo de Microsoft Linq pero siguiendo la sintaxis de Javascript, o bien basándose en la base de datos para navegador TaffyDB.
- Servidor de aplicaciones. Son muchas las opciones, como he mencionado antes. Pero la amplia adopción de CommonJS crea un rico ecosistema de opciones que otros lenguajes no cubren. Esa variedad que ha aparecido en muy poco tiempo es la mejor prueba de que, probablemente, esta nueva década sea la de la amplia adopción de Javascript. Otros estándares que ya están en el cliente, como los Web Workers o el ya famoso y estudiado XMLHTTPRequest que mueve a AJaX, serían de mucha utilidad en el servidor.
- En el navegador se echa en falta un sistema de empaquetado de aplicaciones al estilo los
.jar
de Java que optimizaría la descarga al no exigir varias conexiones para obtener todos los datos. Otro estándar que echo en falta es un lenguaje basado en JSON, que equivalga a HTML y que sea aceptado por los navegadores. Queindex.jsml
empezase a sustituir al omnipresenteindex.html
sería un buen paso. Ya hay proyectos que sustituyen el CSS y al XHTML, pero un estándar que, al igual que XUL, permitiese crear formularios optimizados para aplicaciones web podría dar un empuje definitivo que arrinconase más a las aplicaciones tradicionales de escritorio...