Organ1k, my JS1k contest entry
Recently, word came through the twitter-nets that JS1k, a 1 kilobyte JavaScript competition, was accepting entries. Now, I haven’t done anything “fancy” in a while, but I used to do that kind of stuff all the time (you know, before I was married).
So I asked myself, “Ben, can you do something extra fancy in exactly 1024 bytes of JavaScript?”
I should mention that I’ve wanted to revisit my 2004 DHTML mouse trails JavaScript (written back before I really had any idea what I was doing) for a long time, using the HTML5 canvas
element. At one point, I looked at Processing.js, but at the time I just couldn’t wrap my head around it.
So, last night I sat down, cracked open my old source code (horrible), and started coding… and a few hours later, my code had evolved into Organ1k, an exactly-1024-byte HTML5 canvas-based demo inspired by my original DHTML mouse trails script.
In case you missed the link to the actual demo, it’s Organ1k.
Of course, while the resemblance to the original (version 4, specifically) should be obvious, I’ve taken the opportunity to do a lot of the things that were simply not possible at the time, and I’m pleased with the result.
While Organ1k has been tested in Firefox 3.6, Safari 5.0, Chrome 5, Opera 10.60 and IE9 test build 4, it’s a bit slow in Firefox, so I’d recommend against that. Still, it should be relatively zippy in all of them (provided you have a modern computer, of course).
Edit: Organ1k has been accepted and is now listed at the JS1k demos page, so check it out now. And while you’re there, be sure to take some time to check out all the other amazing entries!
A few words on minification for the JavaScript savvy
First, please realize that I’m not at all advocating using minification techniques like these under normal development conditions, because they make your code a totally unmaintainable mess. If that last sentence confused you, read the “Avoid premature optimization” section of my article Style in jQuery Plugins and Why it Matters.
That being said, if you want to see a whole bunch of absolutely silly, over-the top byte-saving optimizations, feel free to view the unminified source on GitHub, where I have full documented and commented (with examples) all the different things I did. Just in case you were curious, my goal was not to make it as small as possible, but to make it exactly 1024 bytes… which was especially difficult whenever I went below the limit and have to un-minify my code.
Also, since developing something that meets requirements like these is an extremely iterative process, it’s not a bad idea to create a build script of some sort that can help streamline the whole “minify + remove unnecessary code + measure final size + test in browser” process.
These are some of the byte-saving techniques that I used:
- vars declared as function arguments (avoids 4 chars lost to the
var
keyword plus trailing space) - splitting a string into an array, saving 2 bytes (from quotes) because it was joined with a number, eg.
'a1b1c'.split(1)
- using minifiable references to anything that gets reused, eg.
document
,setInterval
,Math
,Math.PI
,pi_over_180
, etc - initializing multiple variables/properties in a single statement, eg.
a = b.c = 0
- assigning variables as function arguments or in conditionals, eg.
if ( a = 1 ) { ... }
- using ternary conditionals instead of
if
/else
blocks, eg.a < 1 ? b = 1 : a < 2 ? c = 2 : d = 3
- decrement loops instead of increment loops where possible
- using
~~
instead ofMath.floor
- using hard-coded values instead of
my_array.length
(this can get scary without good comments) - closure + vars explicitly declared to help YUI minifier, then stripped from the minified output (no longer necessary!)
- referring to
window
asthis
(no longer necessary, thanks Remy!)
Again, read more about these techniques in the unminified source on GitHub.
Have any feedback? Let me know in the comments, thanks!
a
,b
,i
,br
,p
,strong
,em
,pre
,code
.<pre class="brush:js"></pre>
(supported syntax highlighting brushes:
js
,css
,php
,plain
,bash
,ruby
,html
,xml
)<
instead of<
and>
instead of>
in the examples themselves.