Como curiosidad me pareció muy interesante ayer la noticia de Nihilogic en la que nos mostraba la posibilidad de comprimir ficheros Javascript o CSS en una imagen PNG para luego cargarla mediante Canvas y así poder disponer del código comprimido anteriormente.
La idea, aunque interesante, no me parece factible para la vida real. Principalmente por que no me imagino depurando el código Javascript mirando un fichero PNG, pero para hacer pruebas es altamente atractivo.
(jQuery convertido a PNG :D)
La idea
Ya hemos visto otras formas de minimizar el tiempo de carga de nuestros ficheros Javascript o CSS, y esta no es muy diferente. Básicamente las dos se basan en evaluar el código de nuevo directamente en el navegador como texto, para ello se usa eval()
, lo único que veremos cambiar será la forma de recoger el código.
var x = function(z, m, ix ) { // image, callback, chunk index
var o = new Image();
o.onload = function() {
var s = "",
c = d.createElement("canvas"),
t = c.getContext("2d"),
w = o.width,
h = o.height;
c.width = c.style.width = w;
c.height = c.style.height = h;
t.drawImage(o, 0, 0);
var b = t.getImageData( 0, 0, w, h ).data;
for(var i= 0; i <b.length; i += 4) {
if( b[i]> 0 )
s += String.fromCharCode(b[i]);
}
m(s, ix);
}
o.src = z;
}
Este código se encargará de leer mediante un elemento <canvas />
una imagen que le pasaremos como parámetro. Se encargará de cargar byte a byte para obtener el texto completo de nuestro javascript. Posteriormente lo evaluaremos y dispondremos del código disponible en nuestra página.
¿Como se crean esas PNG’s?
La creación de estas imágenes es bastante sencilla, simplemente tendremos que leer el texto que deseamos convertir a PNG y generaremos una imagen pixel a pixel con el valor de cada carácter.
def string2png( string, output )
image = Magick::Image.new 1,string.length
for i in 0 .. string.length
color = '#%02X0000' % string[i]
pixel = Magick::Pixel.from_color color
image.pixel_color 0, i, pixel
end
image.compression = ZipCompression
image.write("png8:"+ output)
image = nil
end
En este código en Ruby vemos que después de leer el código lo recorremos letra a letra y vamos generando un pixel de un color diferente (dependiendo de la letra que estemos procesando). Ver el código completo.
¿Por que usar esto?
Personalmente no lo usaría para un uso real, pero la reducción de peso de ficheros en las pruebas realizadas con Javascript han sido bastante interesantes:
prototype-1.6.0.2.js
123 KB Javascript compressed to 30 KB PNG (24%)
jquery-1.2.3.min.js
53 KB Javascript compressed to 17 KB PNG (32%)
excanvas.js
24 KB Javascript compressed to 8 KB PNG (33%)
excanvas-compressed.js
10 KB Javascript compressed to 5 KB PNG (50%)
dijit.js
46 KB Javascript compressed to 16 KB PNG (35%)
Aunque son valores interesantes, las pruebas hechas con digit-all.js en la misma página de Nihilogic reflejan que para cargar los 70Kb comprimidos en PNG (255Kb sin comprimir) necesita cerca de 5-6 segundos en evaluarlo. Periodo que el navegador se queda prácticamente parado.
Por otro lado, navegador como IE6 no soportan el elemento canvas nativamente, lo que nos limita su uso prácticamente en la mayoría de sitios web.
Conclusiones
Como curiosidad está la mar de bien, incluso para demostrar lo que se puede hacer con ingenio y las herramientas que ofrece HTML5. Pero nada más, gZip ofrece una reducción interesante además lo incorporan la mayoría de navegadores.
Via