2011/04/01

Minimización de fuentes II. Minify.

Como os decía ayer, hay una alternativa a la compresión en tiempo de desarrollo de los fuentes javascript y CSS, y esa alternativa se llama Minify (http://code.google.com/p/minify/).

Lo que hace que funcione esta librería PHP es que incluye en motor de compresión de JSMin que vimos ayer portado a PHP para javascript y CSS (y también HTML) de modo que en tiempo real se minimizan los fuentes ya sean uno a uno o en grupos, lo que además de reducir el tamaño, permite reducir el número de peticiones HTTP.
Antes

Después

La instalación es sencilla... se descarga el paquete y se descomprime en un directorio accesible desde PHP del servidor. A partir de ahí, suponiendo por ejemplo  que se ha descomprimido en el document root, solo habrá sustituir las inclusiones javascript y CSS por
<script source="/min/b=directorio_base&amp;f=fichero1.js,fichero2.js,fichero3.js"></script>
<link rel="stylesheet" href="/min/b=directorio_base&amp;f=style1.css,style2.css" type="text/css">
El directorio base con el b=directorio es opcional y se puede incluir en el nombre de cada fichero.
Alguno dirá... "espera! y qué pasa con las directivas url() de CSS... si me cambian la localización del CSS, se me escogorciará todo!" y tiene razón... pero el propio minify es capaz de analizar el directorio del CSS y generar el código final con los url cambiados para que se mantenga el camino hasta el fichero indicado en el url.

La ventaja es que las minimizaciones se cachean de modo que cuando se vuelve a pedir el códido minimizado si los fuentes no han cambiado, se devuelve el caché incluso pre-comprimido por gzip haciendo que vaya muy rápido. En el momento que se cambia un fichero, se reminimiza todo y se devuelve el resultado.

Ahora llega el momento es que se está en medio del desarrollo y se quiere depurar el código porque algo está dando lata. Muy fácil... solo hay que añadir al final del URL la coletilla &debug=true (&amp;debug=true) para que no minimice el código y además añada como comentario el número de línea original antes de concatenar los ficheros unos con otros.

Este es el funcionamiento base, pero puede que os pase como a mí, que no me gusta dar "pistas" de la estructura interna de la página o tener mayor control sobre qué se incluyo en el minimizado o no. Pues ello se consigue definiendo grupos de minimización.

Los grupos se configuran en el fichero /min/groupsConfig.php dentro del paquete de minify y son un array asociativo con clave el nombre del grupo y con valor un array con la ruta al fichero a minimizar. Se puede usar en la ruta del fichero el pronombre '//' al principio para indicar el document_root del servidor web. Un ejemplo es:
return array(
    'js' => array('//js/file1.js', '//js/file2.js')
);
Para CSSs seria igual. Para incluir un grupo, solo hay que cambiar el /f (&amp;f) del url minimizado, por /g (&amp;g) indicando a continuación el nombre del grupo.

Como esto puede ser un tanto engorroso, minify proporciona una herramienta para generar el código a incluir en el groupsConfig.php simplemente abriendo la dirección /min de nuestro servidor sin parámetros, con lo que se muestra una interfaz para añadir ficheros y al final se genera el código PHP a pegar.

Minify, además tiene estructura modular y se le puede integrar el toolchain para el closure compiler de google, otros motores de minimización como por ejemplo el jsmin+ o el yui. Para ésto hay que mirar la documentación.

No hay que llegar a tantas virguerías ya que el caso más común que se puede dar es que haya código ya minimizado porque forme parte de otro paquete y que no se quiera minimizar ya que al reminimizar un código minimizado con otro motor de lugar a un código inválido y nos volvamos locos al no poder depurar. La solución es usar el módulo de trasformación de código que se usaría para cosas más complejas como he dicho antes pero forzando que la salida sea igual a la entarada. Un ejemplo con el jQuery:


//'//directorio/js/jquery-1.5.1.min.js' // Línea inicialnew Minify_Source(array('filepath' => '//directorio/js/jquery-1.5.1.min.js','minifier' => create_function('$a', 'return $a;'))) // Línea nueva
Realmente es más complicado explicarlo que usarlo. Quizás no de la mejor tasa de compresión de todas, pero funciona tan bien y es son tan fáciles de mantener la reglas que no da ni pereza. Yo lo que hago es generar un grupo para el CSS con todos los CSS aplicables y 2 ó 3 grupos de javascript con más o menos paquetes en función del uso más normal en las distintas páginas e incluyo el URL correspondiente en cada página.

No hay comentarios:

Publicar un comentario