Compress CSS and JavaScript Using PNGs and Canvas

This is a sneaky trick. It was devised by Jacob Seidelin at and has been used by some participants in the 10K An Event Apart competition, though there is some contention as to whether it’s in keeping with the spirit of the event.

That said, it’s interesting to see how it’s done, so let’s have a look. Here are the steps:

1. Minimize your application
The first step is to squeeze your final CSS and JavaScript to the smallest possible size using any decent compression tool.

2. Encode your CSS and JavaScript as a graphic
This is the tricky part. You need to convert your ASCII-encoded CSS and JavaScript files into a single binary image. The PNG format is best because it’s lossless (your code is preserved), uses zlib compression, and is supported by all browsers.

Web developer Cal Henderson has published his research and PHP/Perl code that converts code to an image using various formats such as 1-bit, 8-bit, 24-bit, and so on. You can view the jQuery library as a 1-bit square here.

The PNG can be reduced in size further using tools such as and PNGOUT.

3. Extract the code from the image
We now need to load the image and convert it back to executable code. This can be achieved by loading the image into a canvas element using the drawImage() method. Individual pixels are then read using getImageData(), and converted to a string that can be passed to eval() or embedded into the DOM.

Results vary, but file size savings of 75% can be achieved. In a few cases, the image format can beat files compressed with Gzip. So you could enter the 10K competition with 40Kb of code!

Does this have a real-world use?

So, apart from cheating at contests, does this technique have any real-world application? It’s an interesting hack, but Gzipping source files on the server will normally result in better compression and it’s far easier to implement.

However, I could see the technique being used for steganography, or to encrypt sensitive code from novice hackers. Very cool, but would you use it?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • schwoortz

    very interesting! I wonder what #3 means in terms of client-side processing. I do a lot of mobile web dev lately, and I wonder, if our favorite smartphones would benefit from this approach. Gotta try. I guess it’s too heavy a task for those rather weak cpu…

  • Aleksejs

    Unfortunately I see it more as an yet another vector for attacks. Imagine – now you have to virus-scan all (or at least PNG) images. Malicious code now can be spread over multiple images and checking is done assembling all parts and executing every webpage in sandbox (very costly process).

    • Craig Buckler

      I don’t think it’d be easy to detect malicious code within a PNG — it could be encoded in any way you like.

      Besides that, the code wouldn’t run unless it was extracted first, so you’d need to inject a canvas PNG reader on to the page. If you can do that, you wouldn’t need a PNG in the first place!

      • Aleksejs

        Yes, and besides that – most AV software does not even check images. Ever tried enabling all web content scanning with heuristics and other bells and whistles in your AV? :D When I did that – internet speed dropped from 100mbps to 9mbps.

  • digitalgravy

    Ok, so the obvious use of this would be to shrink your code. That’s a bonus. However, ask yourself why are you wanting to shrink your code?
    If your answer is to save bandwidth, and not loading times then my next point is null and void.
    However, if the answer to that is to save loading times then we must ask how much extra work is the unencoding and eval’ing of the code? Take a browser such as the Trident series (Internet Explorer); all bar the latest alpha of IE9 have godawful JavaScript rendering.
    I’d like to bet that the time you save with shrinking your code will become negligible when compared to the time taken to actually use the code.

    Oh and IE doesn’t actually support the CANVAS element!

  • brothercake

    Most obvious real-world use I can think of is as an exploit :(

    Definitely not in the spirit of the 10K challenge, either way!

  • Tarh

    This reminds me of the esoteric programming language called Piet; it is a language whose interpreter decodes instructions stored directly in bitmaps:

  • Justen

    That’s a really neat hack, but in practical application it is both browser dependent and highly in violation of the open-sourceyness of the web. I also wonder how it may affect script optimization in javascript interpreters. I can’t imagine even *thinking* about using this approach except to get around code size limitations in competitions, as it was.

  • czarzhan

    This is very interesting. I would like to learn more. For example, how much loss of data could be expected if I printed the png and then scanned the print (assuming a 72dpi print, a relatively small amount of print (less than 200 characters) and a scan by a smartphone)?

    • Wardrop

      They already have the technology. Ever heard of barcodes :-)

      There are barcodes out there that pretty look identical to the black and white image linked to in this article.

      • czarzhan

        Thank you, Wardrop, but what I had in mind is something with a not immediately recognizable format.

  • Varda

    Nice trick and interesting that this can be done, but in normal website development I’d say this is pretty inconvinient.
    It makes the CSS damn hard to edit, you’d have to make a png image of it every time to fix even a minor problem. And as a bonus it makes the whole style system very confusing, try leaving this for someone who wants to edit the CSS to figure out.
    So even if it did work on all major browsers I wouldn´t use it unless I really had no other choice(not that i really can imagine a situation like this).

  • Scott (in online advertising)

    Coincidentally, 40Kb is the upper limit for standard banner ads…

  • mathieuf

    I agree with those who note this is an exploit pathway. I hope anti-virus vendors check for and stop such hidden code, or start to, and this will further reduce any honest use of this technology.