martes, 12 de febrero de 2008

JS, Comprimir JavaScript y de paso CSS

AJAX está en uno de sus mejores momentos y de paso le ha dado un empujoncito al tan poco querido JavaScript.
Ahora vemos sitios con un gran porcentaje de JS y eso ha traído con sigo varias cuestiones como la seguridad del código como el tamaño de los archivos .js.
Los archivos .js se descargan al cliente como archivos de texto plano y son fácilmente visibles por cualquier ojo curioso y al mismo tiempo si el programador fue muy juicioso comentando, indentando y escribiendo nombres de variables claros los .js empiezan a pesar más Kb de lo normal.
Para solventar esto hay 3 técnicas que permiten hacer el código más pequeño en peso y menos legible para el ojo humano (solo menos legible, ya que existe obligatoriamente la inversa para estos métodos).

* Minification (No se como se dice en español):
Básicamente lo que hace es eliminar comentarios, espacios y tabuladores al código.
Está técnica es muy segura para el código (de aquí en adelante cuando hablemos de seguridad estamos hablando de la compatibilidad del código generado) pues no lo modifica demasiado, no requiere tampoco un proceso de traducción pues el código sigue intacto, pero, no comprime demasiado ni da mucha seguridad.

El mejor de su genero es el JSMin

* Obfuscation (Tampoco se como se dice en español):
Está técnica, además de hacer un Minification modifica el código cambiando el nombre las variables y de las funciones por nombres más pequeños (obviamente menos descriptivos).
Por modificar el código tan agresivamente es menos seguro (quiero decir que en su traducción el .js puede quedar inservible), pero al mismo tiempo su peso es menor y su lectura más complicada. También requiere de una traducción por parte del cliente (ya que las funciones no se llaman como deberían) y esto es tiempo y recursos en la máquina del cliente.

Entre las opciones que hay son:

- YUI Compressor:
Escrito en Java y uno de los más conocidos, también uno de los más seguros. Además también sirve para CSS.

- Packer:
Para mucho es el mejor, tiene buena compresión, aunque se cree que no están seguro como YUI pero si tiene un alto nivel de seguridad.

- Crunchy:
Otra opción de obfuscation, es más agresivo que YUI y no es tan seguro.

- JSCruncher Pro:
Es comercial, no lo he probado pero se dice que es bueno.

- Dojo ShrinkSafe:
Se dice que es uno de los más seguros.

- JSMart:
No lo he probado, comprime también CSS.

Encontré también una paginilla interesante que compara algunos de los métodos que describimos arriba, CompressorRater.


* GZip o HTTP Compression:
En esta técnica se pasa un .js o un .css o .html (si, también sirve) comprimido al navegador, este lo descomprime y lo ejecuta. Todo lo que se pasa está compreso por ende se usa menos ancho de banda del servidor, pero, más RAM al tener que comprimir todo antes de pasárselo al cliente. El cliente a su vez debe descomprimir antes de ejecutar.
Es una técnica no siempre tan segura ya que no todos los navegadores soportan gzip (en el link de arriba hay una lista de navegadores que lo soportan, está en ingles), he escuchado que IE 6 tiene un error leyendo ciertos contenidos comprimidos.

Encontré una página que explica muy bien como usar esta técnica en gonzo.teoriza.com:
Parte 1
Parte 2


Conclusión
Comprimir nuestros scripts puede tener ventajas en el uso del ancho de banda (por ende $$$) pero también desventajas en el uso de la RAM tanto del servidor (gzip) como en el cliente (obfuscation).
Las pruebas con nuestros scripts nos dirán que técnica o técnicas usar y en que casos (no olvidar las pruebas con el navegador).
No creo que sea muy recomendable para el cliente hacer gzip y obfuscation al mismo tiempo, pero no le veo problema al gzip y al minification.
No olvidar, siempre hacer una copia de seguridad antes de hacerle un minification o un obfuscation a nuestros archivos.
Los archivos ya modificados son buenos para el servidor final (producción) pero para desarrollo definitivamente toca con los normalitos.


Espero les sea de utilidad y quedo en espera de comentarios y/o correcciones.

martes, 5 de febrero de 2008

AS2, JSON vs XML

Después de haber probado JSON con AS3 quise hacer lo mismo pero con AS2 y esto fue lo que descubrí...

1. Descargué la clase JSON desde la página oficial (http://www.json.org/). También hay otra clase del mismo autor rondando por la red, tiene la ventaja de ser estática, pero, es notablemente más lenta.

2. Cree un archivo de Flash con 2 DataGrid, el primero lo llamé "dataj_dg" y el otro "datax_dg".

3. Le cree una clase al documento:


Básicamente lo que hace es cargar un JSON y un XML (con los mismos datos) y convertirlos en un DataProvider para pasárselos al los Datagrid. Al final traza el tiempo que demoró procesando cada archivo (la carga no cuenta).

4. Cargué la clase en el primer frame de mi película con este código:

import Main;
var oMain:Main = new Main(this);


5. Usé los mismos archivos .json y .xml del ejemplo de AS3.

6. Lo ejecuté y.....

Tiempo JSON: 17
Tiempo XML: 2

7. Después calculé el tiempo de JSON usandolo después de parseado y los resultados fueron:

Tiempo JSON: 1
Tiempo XML: 2

8. Nuevamente sorprendido.

El test se hizo en un PC Athlon X2 4000+ con 1.87 GB de RAM

Conclusión:
Con JSON usamos mucho menos código ya que se usa como un objeto.
La parseada de JSON come mucho proceso. Si el JSON se carga una sola vez y se usa mucho podría ser una muy buena opción.

Quedo en espera de comentarios, dudas o correcciones.

viernes, 1 de febrero de 2008

AS2, Clase administradora de versiones

Hace poco he creado una sencilla clase que me ayuda en la administración de las versiones de mis otras clases o archivos .fla.

Cuando se trabaja en proyectos grandes, con varias personas en el equipo y con mucho movimiento en algunas ocasiones sería bueno saber que versión de la aplicación está corriendo en el servidor.
Con esta sencilla clase se registra cada clase en el contructor (o donde quiera) y esta se agrega en una lista de clases y versiones. Cuando se desea ver el reporte de versiones se llama una función que le devuelve el reporte de versiones.

Veamos un ejemplo...

import com.npi.debug.Version;

class Test1{
public function Test1() {
Version.log("1", This);
}

public function toString():String {
return "TEST1";
}
}


Como ven con una simple línea de código se guarda la versión de la clase (en este caso Test1).
También se puede notar que la clase Version es estática, de hecho usa un patón de diseño llamado Singleton.

Veamos las funciones publicas de nuestra clase Version...


public static function getInstance():Version
Devuelve una instancia de la clase Version. Usado por el patrón Singleton.

Ejemplo:
var oVersion:Version = Version.getInstance();


public static function log(sVersion:String, oClass:Object):Void
Agrega una clase u objeto a la lista de versiones.
Esta es una forma corta de agregar clases internamente llama a otra función llamada "add" que veremos más adelante.

Tiene 2 argumentos:
* sVersion:String que es el número de la versión.

* oClass:Object que es la clase a versionar.
Si la clase tiene una función toString se puede usar this o la referencia a dicha clase, también puede escribir el nombre directamente.

Ejemplos:
Version.log("1b", This);
Version.log("8.3 RC 4", "GAME FLA");
Version.log("1.5.2", "GAME");



public function add(sVersion:String, sClassName:String):Void
Igual que la anterior, agrega una clase u objeto a la lista de versiones.
La diferencia está en el argumento sClassName que es un String no un Object y en la forma en que se llama al no ser estática y usar el patrón Singleton (eso la hace levemente más rápida).

Ejemplos:
Version.getInstance().add("1b", This.toString());
Version.getInstance().addg("8.3 RC 4", "GAME FLA");
Version.getInstance().add("1.5.2", "GAME");



public function getVersions():String
Retorna un reporte de las versiones. Usa el patrón Singletón.
Dice el número de clases registradas y las organiza alfabéticamente.

Ejemplo:
Trace("Traza...");
Trace(Version.getInstance().getVersions());

Traza...
REPORTE DE VERSIONES (3)
* GAME v1.5.2
* GAME FLA v8.3 RC 4
* TEST1 v1b



Tip. Se puede trazar el reporte al presionar ciertas teclas (puede ser CTRL + 7).

var myListener:Object = new Object();
myListener.onKeyDown = function() {
if (Key.isDown(Key.CONTROL) && Key.getCode() == 55) {
trace(Version.getInstance().getVersions());
}
};
Key.addListener(myListener);


Version.as


Quedo en espera de comentarios, dudas o correcciones.

jueves, 31 de enero de 2008

AS2, EventDispatcher modificado

En algunas ocasiones los listeners de nuestra aplicación se quedan vivos aún cuando ya no los necesitamos y eso nos acarrea que la aplicación tenga unos resultados poco esperados (esto sucede sobre todo si usamos interfaces o programamos de afan :) ).
Por esa razón he modificado ligeramente la clase EventDispatcher de Macromedia añadiéndole algunas funcionalidades interesantes que listaremos a continuación...

1. A la función addEventListener se le añadió un nuevo argumento llamado "tagName":
Es un String con el cual podemos agrupar listeners de la misma funcionalidad. Se ve mejor con un ejemplo...

this.addEventListener("clic", onClic, "botones");
this.addEventListener("focus", onFocus, "botones");
this.addEventListener("exit", onExit, "botones");

Como ven todos tienen el mismo tagName ("botones" en este ejemplo).

2. Se añadió una nueva función estática "removeEventListenersForTagName":
Con esta podemos eliminar todos los listeners que tengan cierto tagName.

EventDispatcher.removeEventListenersForTagName("botones");
EventDispatcher.removeEventListenersForTagName("registro");
EventDispatcher.removeEventListenersForTagName("juego1");

3. Se añadió una nueva función estática "removeEventListenersForEvent":
Con esta podemos eliminar todos los listeners que tengan cierto evento y fueron registrados por nuestro EventDispatcher.

EventDispatcher.removeEventListenersForEvent("clic");
EventDispatcher.removeEventListenersForEvent("focus");
EventDispatcher.removeEventListenersForEvent("exit");

Hay que tener cuidado con esta función ya que se busca ese nombre de evento en toda la aplicación.

4. Se añadió una nueva función estática "removeEventListenersForScope":
Con esta podemos eliminar todos los listeners de cierta clase u objeto.

EventDispatcher.removeEventListenersForScope(this);
EventDispatcher.removeEventListenersForScope(this.oMain);
EventDispatcher.removeEventListenersForScope(RegisterManger);

5. Se añadió una nueva función estática "removeAllEventListeners":
Con esta eliminamos todos (repito, TODOS) los listeners que fueron registradas por nuestro EventDispatcher.

EventDispatcher.removeAllEventListeners();

6. A la función dispatchEvent se le añadió un nuevo argumento llamado "deleteListener": Es un Boolean que le indica a la función si debe eliminar el listener después de ejecutarlo. Si es True entonces despacha el evento y lo borra inmediatamente, si el False o undefined o null lo despacha pero no lo borra.

this.dispatchEvent({type:"clic", target:this}, true);
this.dispatchEvent({type:"clic", target:this}, false);
this.dispatchEvent({type:"clic", target:this});



Como ven no tenemos que ponernos a eliminar uno por uno los listeners que creamos, solo los agrupamos por un tagName o los encapsulamos en cierta clase y los matamos todos de un solo golpe.

Otra ventaja es que es 100% compatible con el EventDispatcher de Macromedia entonces podemos cambiar tranquilamente el import de mx.events.EventDispatcher por el de nuestro EventDispatcher.
Las demás funciones siguen igualitas y se utilizan de la misma manera (incluido el "initialize").

EventDispatcher.as


Quedo en espera de comentarios, dudas o correcciones.

miércoles, 30 de enero de 2008

AS3, JSON vs XML

Tenía mis dudas con respecto a si JSON sería más ágil que XML en AS3 dado el brusco cambio que hicieron los de Adobe con la nueva implementación de ECMAScript para XML (E4X).
Pues decidí verificarlo y esto fue lo que sucedió...

1. Descargué el "as3corelib" de Adobe (http://code.google.com/p/as3corelib/). Es un proyecto de los laboratorios de Adobe que finalmente lo lanzaron al público y lo colocaron en los servidores de Google. Permite la codificación / decodificación de JSON y otras cositas cheveres como MD5, SHA1, etc.

2. Cree un archivo de Flash con 2 DataGrid, el primero lo llamé "dataj_dg" y el otro "datax_dg".

3. Le cree una clase al documento:


Básicamente lo que hace es cargar un JSON y un XML (con los mismos datos) y convertirlos en un DataProvider para pasárselos al los Datagrid. Al final traza el tiempo que demoró procesando cada archivo (la carga no cuenta).

4. Cree los archivos de datos (el JSON lo saqué del ejemplo del as3corelib y el XML de la conversión de este).

mashedpotato.json


mashedpotato.xml


5. Lo ejecuté y... taraaaaan!!


Tiempo JSON: 21
Tiempo XML: 4

6. No contento con los resultados, calculé el tiempo tanto del JSON como del XML después de creado y parseado los datos, y el el resultado fue:

Tiempo JSON: 4
Tiempo XML: 2

7. Valla!!! que diferencia. Tonces traté de hacer modificaciones como cargar primero el XML y después el JSON, pasar el JSON decodificado directamente o convertido a Objeto pero finalmente el resultado fue el mismo.

El test se hizo en un portatil Celeron 2.59 GHz con 512 de RAM.

Conclusión:
Es muy difícil competir con un objeto nativo como lo es el XML dentro de AS3.
El tiempo de parseo de JSON es relativamente alto. Su lectura después de eso es buena.
No es que JSON sea una mala opción solo que las mejoras que hicieron en AS3 son muy buenas :)

Quedo en espera de comentarios, dudas o correcciones.

martes, 22 de enero de 2008

Dónde aprender?

No creo conveniente crear un manual de los lenguajes de nuestro interés ya que por Internet hay muchos de ellos muy buenos, completos y en español. Por esa razón vamos a listar algunos links que podrían ayudarnos en la laboriosa tarea de aprender...

ActionScript
* La ayuda de Flash:
El mejor lugar para aprender AS2 y AS3 de mano de sus propios creadores.
* CristaLab:
Excelente sitio con muy buena información sobre AS2 y AS3, además de otros temas tecnológicos.

Ahora unos libros super recomendados...
* Essential ActionScript
(Inglés) Excelente libro que se extiende en el aprendizaje de AS. Hay versión para AS2 y otra para AS3.
Está en inglés pero se que existe una en español de la versión AS2 que la distribuye Anaya Multimedia.
* ActionScript Cookbook
(Inglés) Libro lleno de código con soluciones a problemas comunes en AS. Hay versión para AS2 y otra para AS3

AJAX
* El rincón de AJAX 2.0:
En esta página se encuentra un tutorial de AJAX excelente.

PHP
* La ayuda de PHP:
La referencia oficial de PHP en el formato e idioma que prefieras.
* Taller de PHP:
Un PDF muy completo, algo viejito pero enseña PHP de manera sencilla.

A medida que consiga más links los iré añadiendo, pero de momento hay mucho que leer.

Nace otro blog...

Si, así es. En esta ocasión trataremos temas sobre programación web, entre los cuales estarán tecnologías como HTML, CSS, AJAX, PHP, ActionScript (Flash) y Flex. Nos centraremos especialmente en estas dos últimas. Es posible que hablemos de otras (un tanto olvidadas por mi pero no por la humanidad) como .Net y JSP.

Como ven, hay muchos temas por hablar en este nuevo blog.

Trataremos (nótese la negrilla) de tener un nuevo artículo cada semana, así que recomiendo añadan esta dirección en su lector RSS favorito.

No es más, estaré atento a sus comentarios y/o aportes a esta comunidad.