Descarga: comprimir-css-y-js.zip (incluye YUI Compressor 2.4.8 y el script de Python).
Al momento de desarrollar aplicaciones web, vía CGI o WSGI, con Django, web2py, Pyramid o cualquiera fuese la librería, incluso páginas estáticas o en otros lenguajes de programación, comprimir archivos estáticos o que no cambian muy a menudo su contenido es una buena práctica para acelerar el tiempo de carga tu web y mejorar la experiencia del usuario. En el caso de archivos de JavaScript y CSS, «comprimir» o «minimizar» es, principalmente, remover comentarios y eliminar saltos de línea y espacios en blanco innecesarios. Para el caso de JavaScript en particular, algunos compresores también incluyen optimización y ofuscación del código.
En este artículo estaremos utilizando YUI Compressor, un programa escrito en Java para comprimir archivos de JavaScript y CSS. Puedes descargarlo desde este enlace, y la máquina virtual de Java (necesaria para ejecutarlo) desde aquí. En la página encontrarás todas las opciones disponibles, pero básicamente funciona con el siguiente comando.
java -jar yuicompressor-2.4.8.jar -o styles.min.css styles.css
En donde styles.min.css es el nombre del archivo de salida (que será creado automáticamente) y styles.css el archivo de entrada (aquél que queremos comprimir). YUI Compressor detecta el tipo de archivo (JavaScript o CSS) en base a la extensión del nombre del fichero (.js o .css).
(Nota: si estás usando otra versión de YUI Compressor, recuerda indicar correctamente el nombre del archivo .jar; al momento en que escribo este artículo la última versión disponible es 2.4.8.)
Veamos un ejemplo. Considerando el siguiente archivo chat.js:
var ws;
var username;
function onKeyUp(event)
{
if (event.keyCode == 13)
sendMessage();
}
function sendMessage()
{
message = document.getElementById("message");
if (message.value)
{
ws.send("<strong>" + username + "</strong>: " + message.value);
message.value = "";
}
message.focus();
}
function checkSupport()
{
if (!("WebSocket" in window))
{
document.getElementById("login").innerHTML = "Este navegador no soporta WebSockets.";
}
}
function loadChat()
{
username = document.getElementById("username").value;
if (!username)
return;
document.getElementById("login").hidden = true;
document.getElementById("chat").hidden = false;
messages = document.getElementById("messages");
messages.innerHTML = "";
ws = new WebSocket("ws://localhost:9998");
ws.onopen = function()
{
ws.send(username + " ha ingresado al chat.");
};
ws.onclose = function()
{
chat.innerHTML = "Se ha perdido la conexión."
};
ws.onmessage = function(evt)
{
messages.innerHTML += evt.data + "<br />";
messages.scrollTop = messages.scrollHeight;
};
}
function closeChat()
{
ws.send(username + " se ha desconectado.");
ws.close();
}
Ejecutamos YUI Compressor:
java -jar yuicompressor-2.4.8.jar -o chat.min.js chat.js
Y el resultado en el archivo chat.min.js es el siguiente:
var ws;var username;function onKeyUp(a){if(a.keyCode==13){sendMessage()}}function sendMessage(){message=document.getElementById("message");if(message.value){ws.send("<strong>"+username+"</strong>: "+message.value);message.value=""}message.focus()}function checkSupport(){if(!("WebSocket" in window)){document.getElementById("login").innerHTML="Este navegador no soporta WebSockets."}}function loadChat(){username=document.getElementById("username").value;if(!username){return}document.getElementById("login").hidden=true;document.getElementById("chat").hidden=false;messages=document.getElementById("messages");messages.innerHTML="";ws=new WebSocket("ws://localhost:9998");ws.onopen=function(){ws.send(username+" ha ingresado al chat.")};ws.onclose=function(){chat.innerHTML="Se ha perdido la conexión."};ws.onmessage=function(a){messages.innerHTML+=a.data+"<br />";messages.scrollTop=messages.scrollHeight}}function closeChat(){ws.send(username+" se ha desconectado.");ws.close()};
Ahora bien, en lugar de ejecutar un comando por cada archivo de JavaScript o CSS que dispongas en tu aplicación o página web, puedes utilizar el siguiente script que comprime cada uno de ellos dentro de una determinada carpeta. Es decir, busca archivos con extensión .js y .css en las carpetas especificadas y excluye aquellos que finalicen en .min.js y .min.css.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os import listdir
import subprocess
def main():
# Carpetas en donde se encuentran los archivos
# de JavaScript y CSS.
paths = {"js": "static/js/",
"css": "static/css/"}
def get_files(path, ext):
return (f for f in listdir(path)
if f.endswith("." + ext) and
not f.endswith(".min." + ext))
def compress_file(path, filename, ext):
print("Compressing {}...".format(filename))
output_file = "{}{}.min.{}".format(
path, filename[:-len(ext) - 1], ext)
cmd = "java -jar yuicompressor-2.4.8.jar -o {} {}".format(
output_file, path + filename)
subprocess.call(cmd)
print("Done.")
for ext, path in paths.items():
files = get_files(path, ext)
for filename in files:
compress_file(path, filename, ext)
if __name__ == "__main__":
main()
Nótese que este script debe ubicarse junto con YUI Compressor. El script corre en Python 2.x y 3.x, pero Python 2 no acepta rutas relativas (debe especificarse la ruta completa de las carpetas JS y CSS).
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.