JS1k 2014 behind the scenes


In hindsight I probably should have delayed the JS1k contest until I finished the backend. I just needed to updated it to the current state of affairs and use it. But instead, I decide to do something fancy with Bootstrap and AngularJS. For a backend. That nobody else but I will ever see. Yep.

Also, in hindsight I should have gone with "Flappy" as a theme, on the other hand that would probably lead to many of the exact same demo's so maybe it's a good thing I didn't. No I'm happy with "Here be dragons" for JS1k 2014. The early demos submitted already made me smile. Even the Flappy Dragon one, mainly because I really love the sprite :)

The site actually got a major overhaul compared to last year. You might not see much of it though. Most of it is underwater or behind the scenes. I still wanna talk about it for a bit :)


First some obvious optimizations. Chrome reports the whole front-page for JS1k-2013 to be 584k. Of that, 506k are images. Of course there's the demo thumbnail sprite, which takes 349k. And then there's the logo that's 45k. That leaves about 110k of images. Spread over 22 requests. Meh?

So this year I'm spriting all of the front-page images, except for the logo and, of course, the demo thumb sprite. I've asked Diego, who did the amazing logo customization (LOVE IT), for a light-weight image and he delivered. The current 2014 dragons logo weighs a whopping 6k! Haw. The front-page of JS1k 2014 now has a 61k image weight, spread across three images (front-sprite, demo-sprite, logo). I'm not counting the analytics tracking pixel, it's not my problem.

I've also cut down on the stylesheets. The NodeJitsu guys gracefully donated me a Bootstrap design. However, the whole css for 2013 weighted 56k. I manually tore away the styles I did not need, while maintaining the look-and-feel of Bootstrap. The whole css for the 2014 site now weighs 8k "unminified". And of course combines two css files into one.

In short, I've reduced the front-page from 584k over 24 requests in 2013, down to 90k over 7 requests in 2014. Note that this grows slightly because there are currently only 6 demos on the front-page. But it won't cover the difference. I'm saving almost a megabyte per two visitors. Wheee.. Not that I care much from the bandwidth point of view, hosting plan is "unlimited".


Let's talk waterfall. I've cut down about 100ms from the loading time, after above optimizations, by forcing the browser to start loading the two sprites before the stylesheet. Compare these waterfalls...

(The low latency is because my host is a few thousand miles away from me.)



The only trick was putting a script tag before the stylesheet. Otherwise the stylesheet would trigger fetching the sprites once an element used a style with a background:

new Image().src = '/2014-dragons/img/front-sprite.png';
new Image().src = '/2014-dragons/img/sprite.png';

Super simple really. Just a temporary image that loads the image. Technically the browser could destroy the image and stop the image from loading because there are no refs to the image, and it knows that. But it doesn't. The waterfall proofs it. Loading time cut down by about 100ms. Well or whatever. The load time really varies a lot. But the waterfall doesn't.

By the way, the key here is to put the script BEFORE the stylesheet. The stylesheet might force the sprite to load, but it won't do that until much later. If you have to wait for the stylesheet to be fetched anyways, you might as well wait for the sprites to load as well. Note that the stylesheet will block the script (and rest of the page) to load. The script tag doesn't because those images load async.


The submit page got a major overhaul. Well actually, not so much the submit page but the confirmation page. That's a new thing. When you submit your demo, you'll be presented with a page that shows you your demo in the final frameset. Last year I had a lot of submission maintenance because people kept submitting demos that didn't work. They minified the code and didn't bother to check afterwards, or maybe they resized the canvas but the frameset screwed it up, or sometimes the frameset screwed up mouse coordinates. There was always something.

Since I generate these demo pages automatically, of course, I figured I could put the example in an iframe. So I did. I took the script that generated these framesets (you can read more on them here) and put the result in an iframe. It's a bit of an inception case, but it works brilliantly. On top of that I've used the template I have anyways and show you how the demo will be listed on the front-page and demos page. I hope this will lead to a cleaner overview.

The submit page itself did get an important change though. It will store your submission in local storage now. This way you can easily update your demo, keep the same description and other data, and submit again. You won't lose your submission data if you go back or refresh. I hope this will make the whole process a bit easier.


A feature people have been asking for since like the first edition was an alternative way of submitting a demo. I've had phantom bug reports where people couldn't submit their unicode demos because something was dropped, or because a character was converted to a more expensive character, blowing up the size and getting refused by the server. I couldn't reproduce some of these cases and could never resolve them.

To resolve this problem once and for all I've added the option to submit the demo as base64 encoded. The server will decode it for you and the demo is processed as usual. I hope this will take away all the unicode submitting pains once and for all :)


As you have noticed there are now three compos. In the demo scene a compo is another name for competition or section. So there are three compos now: classic, ++, and webgl. I'm basically still rooting for classic. But I understand some people for whatever reason can't get their demo below 1k.

And of course WebGL is not supported by everybody. This little fact sometimes still surprises me, but only 75% can actually see WebGL. Before you think those numbers are skewed, that's 10M people, including sites like youtube and vimeo. Byebye skew.

So yeah there needed to be a webgl compo. Steven Wittens was kind enough to supply a boiler plate for it. Though he's certain that it won't get too much attention because it's just too small. He might be right. I'll evaluate it afterwards and decide to keep it, drop it, or change it based on experience.

The same goes for ++ actually. I'm not too fond of ++ because I think 1k is actually sufficient. People show me every year what kind of amazing things they can do in it, so 2k seems super overkill to me. I'm worried that people will become lazy and just give up, submitting to ++ rather than classic. But again, this is an experiment. I recognize some people just want to submit a 1k>demo<2k script. And that's fine. I hope :)


The boilerplate has been slightly adjusted for classic too. Basically I'm unprefixing requestAnimationFrame, although that might not even be needed in the current landscape. I'm also very tempted to just make a shortcut for it, as it'll improve the rendering quality of demos and that could only help JS1k in the long run, right? But I haven't so far. I struggled because it's nice for JS1k, but not in the spirit of it. You know?


A very common thing for people to do was to resize the canvas to fullscreen. So I've decided to put that in the boilerplate too. It will help bring the quality of the demos up which ultimately is a good thing for JS1k. So no more crappy scrollbars for a nearly-fullscreen experience. Huzah :)


Oh yeah, I also made up my mind on the capitalization of the name. While there's something inside me that dreadfully hates the inconsistent usage of caps and small letters, this is just the way it has to be. I think JS1K is ugly, js1k doesn't work everywhere, Js1k is certainly ugly, and jS1k or js1K are obviously never to be written again. So that leaves JS1k. The JS are caps, because that's what those letters are in "JavaScript", the "1k" is lowercase, even though that technically represents 1000. Ok maybe I should reconsider this choice next year...


I dropped Safari last year because it was not cross platform. That's why IE was never a target platform in the first place. But this year I also dropped Opera. The reason is simple: it stopped releasing Linux builds after 12.0x. I believe the current version is north of 19. So yeah. It's kind of disappointing though. I'd much rather prefer to have a competition targeting five browsers than two.

Mailing list

Ah yeah, I've had a few requests for a mailinglist for notifications. I never deal with that kind of stuff but I figured it'd be a good idea. Especially if I ever do intend to do this JS1konf, it'd be good to have a mailinglist for it. So far the number of subscriptors isn't staggering though, about 30 I think. But hey, it's there, enjoy the silence :p


Okay let's talk backend for a bit. I'm a proponent of security of obscurity as an extra layer of security. So I won't go too deep into details here. But let me at least show you what I saw.

The past few years the backend evolved from a simple list of demo's to a fairly nice dynamic app, just for myself. This is what it looked like:

At the top you see a couple of links to automatically regenerate certain parts of the site. Pretty much everything is templated (no framework) so all I have to do at this point is press buttons and stuff is generated from the submissions.

The second line of links is actually filters for the list partially hidden by the dialog. Don't feel bad about those "rejected" demos, they're mostly duplicate entries that were updated before I got to publish them :)

Ok so then there's the list of demos, which, as I said, I can filter down to if I need to. By default it's filtered to the pending demo's: any demo that was submitted and that I did not yet "un-pend".

For each demo I first check general submission things. The top message is the DM. Some people write entire stories, which is kind of nice :) Most people write a thank you or leave it blank though. Then there's the line that I use to template a tweet. Just the basic information so I can improve it depending on the actual demo. Of course the next three columns are script, "original", and description. I don't care about original too much. I glance to make sure it's not too disturbing. Same for description, actually. It's all escaped so there's little to worry about.

The script part is different though. I have to protect myself so I make sure I don't actually follow a link through the backend (it's secured, regardless, but still). The website, if filled in, won't be an actual link. Neither is the twitter handle for that matter. I'll look at the code, try to spot some obvious problems. So far that hasn't really occurred though. I think just once or twice when a demo actually did something wrong. I like that about the competition, people aren't being complete douches.

When I think it's fine I'll generate the sources. Just two clicks and the whole demo and details are generated. I can access those links to check the demo. I'll remove the files if the demo doesn't pass for whatever reason.

In the bottom left you see a thumb droptarget. I can take a screenshot, drag it over there, and it will upload and sprite up the whole thing. Pretty handy and it saves me a boatload of time in the spriting department.

If a demo is an update I can write down the demo it updates. It will then "hide" the demo from any listing and copy the old thumb to the new demo. Usually updates are minor, so the thumb remains valid. And if they're not, I can always just make a new thumb :)

Yeah so that was my admin screen. But I "got tired of it" and wanted to upgrade it a bit. And I decided I'd do that with Bootstrap and AngularJS. That was an interesting experience. Basically, it taught me a lot on both frameworks. It made the backend look a bit nicer. I suppose a bit more secure, though I don't think there was any risk in the department as it was anyways. Angular pretty much gives you a filter for free, so that's really cool. I can just filter on any demo now. There's also a bread crumb now, which is nice because I'll often jump back and forward between demos of the same submitter. Beyond that I'm not convinced Angular gives me more than what I already had. It's just a different way of going about things. And maybe I needed one way binding more than two way :)

Apart from that, yeah, same old same old. I still have to tweak the filters a bit. Angular is nice, but certain things take more code than they ought to. I suppose every framework has its downsides.


I've tweeted about the idea on a conf. But the last three months have been super intensive for me personally. I'm not going to go into details here, but I simply don't see now how I could have even tried to set up a conf like this. However, now that I'm going to be a contractor I'll have more time and of course have more freedom in what to do when. So there might be a conf in the second half of this year, if I can see a good time for it between other confs. And otherwise the first part of next year, when the number of EU confs seems to be lower.

You should totally sign up for the mailinglist (you can check to only recieve information on the konf, if you want!) to be notified of such an event. Or just follow the @js1k and @js1konf twitter accounts :)


Oh I've finally set up mail for the domain. Makes it easier for me to spam an address without exposing my own domain for that. So if you're dead set on contacting me by mail, you can use sponsor14@notmejs1k.com. Obviously a temporary address for this season, but you should try anyways :)

In case you're interested in sponsoring a prize, that's also where you should send an email to.


Before I stop I'd like to point out that JS1k has no ties to anyone or anything but me. It runs on the volunteering jury that I try to pick fresh each year. It runs on prize donations I get from the community (THANK YOU). But these donations/sponsors have no say in how the competition is ran. And beyond that it runs on whatever free time I put into it, which is probably too much :p

The shared hosting doesn't cost me anything beyond what I already pay anyways, so it's not a financial burden for me. Just time, really. And I'm fine with that. There's a lot of gratitude coming from running the compo. I love all the demos that people send in. The variety makes me smile every time.

But hey, if somebody wants to offer me seven figures for it I'm listening... :p


That's about it. I actually still have to write some code to generate an RSS feed and hook it up to the mailing list. And I will soon. But all I've been spending my spare time on in the past few days is JS1k and I need a bit of a break. So now, it's game time.