The js1k Experience

for me


DISCLAIMER


(Hit the down button if you haven't used this before)







not a JS1K winner






not your definitive guide

to writing good javascript






you may experience javascript

in a different light






you may start getting

OCD tendencies






you may write less readable code






not* how we write code in Zopim**

(*although we are encouraged to try wacky stuff)
(**yeah shameless plug!)



JS1k

Rules

1024 bytes or less (in Javascript)

Must run in Browsers (Firefox, Chrome and Opera)

Demo must with provided shim

Anything for golfing

Should just work

JS1K Shim

<body>
    <canvas id="c"></canvas>
    <script>
        var b = document.body;
        var c = document.getElementsByTagName('canvas')[0];
        var a = c.getContext('2d');
        document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218
        // start of submission //
        SCRIPT
        // end of submission //
    </script>
</body>

My Story


Have been a fan of js1k, never a participant

Spring 2013 announced

Slashdot Effect 5 days before deadline

Decided to do a Tiny Wings clone


The Process



(*you can be happy for every byte saved)
(** look at the crazy hour man!)


My (not so great) Results

(*Tiny Wings took half a year to produce,
what was I thinking I could do in a few days?)




My Ninja Training

Bouncing Beholder




Autumn evening


The training



Start by look for my favorite js1k entries

Observe the similarities

Study the code a little

Read write ups about them




Bytes* Saving tricks

(remember 1024 bytes, not characters)


Variables

Use Single variables when possible
var j=0; var k=0; // before
var j=0, k=0;     // after
var j=k=0;        // better
j=k=0;            // best

Actually, not necessary when using minifiers

Reuse Variables in function paramters 
function (a, b, c, d) { c = a + b; //.. } 

Abuse Globals

Loops

Infinite Loops

while (true); // usualwhile (1); // betterfor (;;); // best

Incremental Loops
for (i=0;i<number;i++) // usualfor (i=number;i--;)    // best
Combine loops
 for (i=0;i<number;i++);
 for (i=0;i<number/2;i++);
vs
 for (i=0;i<number;i++) {
  if (i%2) {}
 }

Functions

Reduce functions since they take up extra 11 bytes each.
 function(){} 012345678901

However, with JSCrush, they could be compressed. Reuse function signatures for more savings with compression.
 x=function(a,b,c,d,e){ y=function(a,b,c,d,e){becomes xF,yF where F = function(a,b,c,d,e)
No need for names, if function is used once
 setInterval(function(a,b,c,d,e){ // blabla });

Conditions


Assign and check
 a=b;if(a){}    // before
 if(a=b){}      // after

Booleans converisons
 if (a==null) {}    // before if (!a){}          // after

Short-circuit operators
 if (a) doSomething()   // usual
 a && doSomething()     // after
 if (!a) doSomething()
 a || doSomething()

Data

Split when appropriate
 ["apple", "banana", "orange", "pineapples"] // before
 "apple0banana0orange0pineapples.split(0)    // after

Use Maths / Procedural Generation if possible

Long Strings
 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' // before
 for(a="",i=30;i--;)a+='z'        // after
 a=Array(30).join('z')            // better

Other Tricks

For extra Canvas
 d = document.createElement('canvas') // before
 d = a.cloneNode(); // after 
Setting Canvas Size
 a.width = window.innerWidth // before
 a.width = innerWidth        // after
Short Canvas Functions
for(i in a)(function(i){a[i[0]+(i[6]||'')]=(''+a[i])[27]?a[i]:function(_){a[i]=_}})(i)
a.globalComposite='destination-over' // before
a.gC('destination-over')             // after
Colors
 c.strokeColor = 'white' // before
 c.strokeColor = '#fff'  // after

Numbers


Flooring Numbers
 Math.floor(x) // before
 x = ~~x       // after

Large Numbers
 million=1000000 // before
 million=1e6     // after

Rounding Numbers
 Math.round(a) // before
 a+.5|0        // after 

Closure Optimizations

Use ADVANCED_OPTIMIZATIONS
 java -jar compiler/compiler.jar --externs externs.js --compilation_level ADVANCED_OPTIMIZATIONS --js source.js --js_output_file output.js
Strip away var declarations
var a,b,c,d,e; a=10,b=....
a=10,b=.... 
Remove Final Semicolon
 bla;bla;bla; // before bla;bla;bla  // after
Strip away leading zeros
 0.5 // before .5 // after

Creating Repeats

If exact values of constants are not critical, round them to the same numbers for maximum compression
  var a = 7, b = 7, c = 7;

Remove Math.PIs
 ctx.arc(x, y, r, 0, 2 * Math.PI); // before
 ctx.arc(x, y, r, 0, 7);           // after

Use global alpha instead of rgba

JSCrush

Originally another entry on js1k, compresses maybe 10% or more of the already minified source

Most entries are currently compressed with JSCrush

Super optimized for js1k entries - both encoders and decoders are below 1k!

JSCrush got some competition from RegPack this round, which saves even more bytes! Winnings entries are packed with RegPack this time.



Workflow

3 Easy Steps



1. Write Code
(no more than few hundred lines)

2. Run

3. Minify, Crush, Repeat

Online Version


  1. Livecode in JSBin
  2. Closure Minify
  3. JSCrush

1. write / Run Code in jsBin



2. Minification


3. JSCrush


Offline Version


Sublime
Git
JS1k Tools
(Nodejs Script + Minify / Uglify + JSCrush)


Freshly Announced

Winning Entries


js1k Spring 2013 finalists



#1 Strange crystals II by Philippe Deschaseaux @ehouais
#2 Furbee, get out of that tunnel ASAP by Roman Cortes @romancortes
#3 3013 The 䕵 space-time fracture by Mathieu 'p01' Henri @p01
#4 Synth Sphere by Noah Weninger@gleurop
#5 Pointillism by Benjamin Bill Planche @b_aldream
#6 3D City Tour by Jani Ylikangas
#7 Comanche by Siorki @Siorki
#8 Color Factors by Pablo Caro @hugoware
#9 Winter Wrap Up by Arne @veubeke
#10 Psychedelic animation by Piotr Stosur
from https://gist.github.com/zz85/5522800

Strange Crystals II



Other Entries


Kinda resonate with this list too

But for true gems, check out the raw entries yourself

Closing Thoughts


js1k is no small thing

its like a marathon
where its better to have weeks of preparations
but everyone's a winner when they finish

it's gonna be lots of fun, ... pain... and interesting learning experiences

leaving with a quote by the current winner...


Philippe Deschaseaux



"IMHO best compression scheme: imagination+time+math skills."






 https://twitter.com/ehouais/status/313943128962908160

Thank you!





Email: zz85nus @ gmail.com

(more reference and links after this slide)

Links


JS1K Site

List of js1k 2013 spring finalists

js1k people to follow on twitter

Tools

Js1k Tools

JSCrush

RegPack

Recommended Readings


Byte Saving Techniques


How to create Tiny Wings like game
(some techniques I used for my entry)


More...


(check out his entire blog and his notebook 1k entry!)

(from creator of Fubree and other intensive graphical js1ks)


Plenty More literature






The js1k Experience

By Joshua Koo

The js1k Experience

A short talk about JS1K I gave at Meetup JS Singapore (http://www.meetup.com/Singapore-JS/events/116409232/) on May 6, 2013

  • 27,032