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.