Showing posts with label Compressor. Show all posts
Showing posts with label Compressor. Show all posts

Sunday, 30 August 2009

Compression Comparison

Comparing Compressor Tools

There are many Javascript compressor tools online and they all do wonderful jobs. What makes the tool I made slightly different is that it allows you to customise a number of compression options which can aid you in getting the best compression rate possible. Whilst most tools offer a simple crunch method and maybe a pack method (changing the code to run through an eval statement to obfuscate the code) they don't allow you to do some simple things that can make a lot of difference such as:

Renaming global objects that are used frequently to reduce size e.g window, document, navigator.

Renaming your own global objects that you may use frequently.

Renaming your own commonly accessed functions to short names.

Replacing calls to document.getElementById with a call to a single letter function e.g $ or G.

These 4 options used together could drastically alter the compression rate of your script.

Also if you have a small script then choosing to pack it as well as crunch or minify it will most likely increase the size of the output rather than compress it. Packing maybe worthwhile if you really want to hide your codes purpose from any user but its totally pointless as anyone can reverse engineer a packed script with a simple line of Javascript either within the Error Console in Firefox or by using one of the unpacker tools available online.


Different Outputs

Also I note that on a few compressors the output may give a misleading impression of success to the user. If a file has been reduced in size by 30% it has been compressed by 30%. Some tools however will show the new file size as a ratio of the old size which would be 70% which is fine. However having a label that just says "Compressed" next to the figure of 70% may lead some people to believe their file has been compressed by 70% when in fact its only been compressed by 30%.

For example take this silly example of a function:


function tested(var2){
var fuv = "hello "
+ "mr smith "
+ "how are you ";
var pid = 1000
var ola = 3343

if(var2==fuv){

var rob = function(){

addEvent(pid,"click",function(e){

var donkey = function(e){
if(fuv == pid){
return true;
}
}
})
}
}
}

Now run it through my compressor


Which outputs the following which has reduced the size by 40.65%


function tested(a){var b="hello mr smith how are you ";var c=1000,d=3343;if(a==b){var rob=function(){addEvent(c,"click",function(e){var donkey=function(e){if(b==c){return true}}})}}}


And now this other compressor tool.


Which outputs the following code and in a box labelled "Compression" it has the value 63.67%.


function tested(A){var B="hello "+"mr smith "+"how are you ";var C=1000var D=3343if(A==B){var E=function(){addEvent(C,"click",function(e){var F=function(e){if(B==C){return true;}}})}}}

Now this is actually the size of the new code in relation to the old and not how much the code has been reduced by which is 36.33%. This is not the only tool that does this and I am sure most people will be aware what the figures actually mean. However because my tool does the opposite and shows the percentage that the new code is reduced by it may lead people to believe one tool has a better compression rate than another when in fact it doesn't.

I am not claiming my tool is perfect as it will never be as it uses regular expressions instead of a Java Engine however most other tools do this as well and I have spent a lot of time handling issues such as missing terminators which other tools like the one above misses. Douglas Crockfords JSMin will just add a new line when a missing terminator is found whereas my tool adds the missing terminator. Other tools will just assume the code has been validated and checked before submission which of course is the best way to avoid any errors at all.


Compression with GZIP

Whats the benefit of minimising your script as compared to using GZIP?

Well GZIP may offer superior compression but its a way of delivering the content to the browser which then uncompress it. It uses server side processing to generate the compressed files which may or may not be a problem depending on the load and the type of file being served.

With minification the code can stay compressed on the server as well as the client plus it will run on older browsers. You also have the benefit that certain minification techniques should actually aid client side performance by reducing processing power e.g reducing the amount of variable declarations or reducing string concatenation by combining the strings together into one variable (see my compressed output)

There is nothing stopping you minifying as well as using GZIP. So if you haven't looked into compression then you should do as its a very simple and easy way of increasing your sites performance.

Saturday, 22 August 2009

Strictly Javascript Compressor

Introducing yet another Javascript compressor

If you read a previous article about creating a script compressor you will know that I like to write my own code purely for sadistic reasons and mainly due to a rare form of OCD that makes me unable to stop coding until something is complete. I am sure this a rather common infliction amongst some in the coding community however it does have its benefits. Although creating a compressor from scratch is a long and painful process it has the upside of increasing knowledge about code syntax, compression techniques, regular expressions, language quirks and much much more. I wouldn't recommend doing it unless you have plenty of time and a desire to know the pain that regular expression based compression can bring.

The Strictly Software Javascript Compressor Tool

I have put a cut down version of my compressor tool up on my website which you can find at the following link: Strictly Javascript Compressor

The online tool only works with Javascript but I have made available a number of options which will allow you to customise the compression process.


Compression Options


The following is a list of all the advanced options available with the online version of the compressor.

Compression Modes: Simple or Complex

Complex mode will try to format the Javascript so that each function is on its own line in the output. If you have a function that contains other functions then only the outer most function will be formatted like this. To accomplish this the engine must try to auto-correct any lines that have missing terminators or brackets by inserting them. In most cases this should work but I cannot guarantee this in 100% of cases due to the engine being based on regular expressions. However if you format your code correctly before hand ensuring all lines are terminated and IF, ELSE statements are wrapped in brackets then you shouldn't get any problems.

Simple mode will not try to put each function on its own line although it will condense multiple occurrences of brackets to one line. This mode will give a longer output as it will contain more carriage returns however it will be less likely to cause syntax errors.

Complex mode will result in a better compression rate than simple mode, sometimes up to 10% or more in certain cases.

Minify Functions

If you have specific global functions that you wish to replace with smaller names then you can provide a list of the functions to replace in the format

[function:minified,function:minified]


For example if you want to replace all occurrances of the function getEl with a minified name of G and the function addEvent with the name A then you can provide a list in the format of:

[function:minified, function:minified]

[getEl:G,addEvent:A]


Important Note:
  • You can only provide 20 functions to rename with this online tool.
  • As my minification process renames long variable and parameter names in local functions with single letter versions starting from a and incrementing up to zz you should avoid using lower case letters for your minified function names to avoid clashes. Its recommended to use upper case letters or use underscores.


Minify Objects

In the same way that you can change function names you can also provide up to 20 global objects that you can replace with minified names. For example if you have global objects Debugger and System you could replace them with _D and _S respectively. Provide this list in the following format of

[object:minified, object:minified]

[Debugger:_D,System:_S]

Important Notes
  • You can only provide 20 objects to rename with this online tool.
  • As my minification process renames long variable and parameter names in local functions with single letter versions starting from a and incrementing up to zz you should avoid using lower case letters for your minified object names to avoid clashes. Its recommended to use upper case letters or use underscores.
Minify Global Objects

This option will replace some standard global objects with smaller versions. The objects it will replace are Window, Document and Navigator. The engine will add the following line of code to the output:

var _w=window,_d=document,_n=navigator


Then it will replace all occurrences of window with _w and so on. Note how I have added underscores to the variable names so not to conflict with the standard minification process of function parameters and variables.

Create a Get Function

This option will replace all occurrences of references to document.getElementById to a minified function call. As this is a very common reference in Javascript code on the web it will save considerable bytes and is very easy to do. The name of the function created will be decided by the value supplied for the Get Function Name option.

Note: If none is supplied the value will be G.

Get Function Name

This option is related to the previous option and only available if you have decided to create a Get function. The value you supply will be used for the minified function name. For example if you provide the following value _S then the following function will be created and added to the compressed output:

_S=function(i){return document.getElementById(i)}


Remove ShowDebug Functions

This maybe a very specific function catering to my own needs but its something I would recommend to all developers. As you create your code you should build in calls to a debug function that will output messages to the console (e.g Firebug, Firebug-lite, IE, Chromes console). This is a much better idea than having to add debug code once a bug has been found and it will save time in fixing the bug. However you should also remove all these functions on a live production environment as you will not want your users to view these messages and even if you turn debugging off inside the function an unnecessary call to the function is made. I always call my debug function ShowDebug. This option will remove all these calls from the code.

If you would like to know more about debugging and creating a custom debug object please read the following blog article.