Contenido

Carga Javascript/CSS con canvas en formato PNG

24 ago

+ 11

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-1.2.3.min.js
(Ver Imagen)

(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

  • No sirve para nada con lo que tarda en procesarlo pero es interesante.

  • Todo sirve. Aunque sea simplemente para aprender algo nuevo.
    Por ahí en el futuro, con la llegada del Firefox 4 y el IE9, y su capacidad de utilizar el gpu esos segundos de diferencias no existan mas, hay que ser optimistas!
    O quien te dice por ahí alguien agarra el código y lo optimiza para que no tarde tanto..
    Piensen que paginas con mucho javascript podrían ahorrarse banda ancha subiendolas a un host gratuito de imagenes.

    • @FaCuZ: Venias bien hasta que dijiste que paginas con mucho javascript podrian subir esas imagenes a host gratuitos.

      No podes hacer semejante negreada, por un lado estas optimizando y por otro lado terminas dependiendo de un host gratuito que puede andar lento, caerse o incluso pueden borrarte la imagen.

      Ahi derrapaste, por el resto esta bien. Capas en algun momento cobre mejor utilidad.

    • @RodolfoGS:
      jajaja, ya lo se, estaba siendo muy optimista.
      De todas formas con un poco mas de javascipt se puede hacer un simple if para cuando no encuentra la imagen, si queres la complicamos un poco mas: subimos la imagen a varios servidores gratis y hacemos un random! si vamos a negrear lo hacemos bien!
      El optimismo me esta matando…..

  • ¡¡Han vuelto los posts a la antigua usanza!!!

  • Yo también creo que no sirve de mucho. Fíjate que el jquery-1.2.3.min.js después de gZipear queda en 15Kb, menos que en PNG, y todos los navegadores modernos lo soportan de manera nativa.

  • La verdad son Fascinantes y creativas las alternativas que se desarrollan para ofrecer a los usuarios una mejor fluidez en las paginas Web. No me quiero imaginar que será de las Paginas Web/Blogs/CMS/Foros (Entre otras cosas) en 5 años, la velocidad de las conexiones serán muy rapidas y potentes, el ancho de banda será ilimitado y las aplicaciones web cada dia mas livianas!

  • Gracias por tus consejos. Voy a tratar esto en mi sitio web.

  • esto no tiene implicaciones en cuanto a seguridad? si se envía código dentro de imágenes quizás los cortafuegos, antivirus, etc. no lo consideren

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.