what is the best JS minifier / obfuscator to use for projects that use JQuery? I'm currently using the closure compiler and I've also tried YUI but they never seem to minify and optimise my function names or variable names, effectively all they do is remove whitespace and comments whereas I'm trying to make my code as small as possible and hide as much as possible.
Any ideas?
Thanks
Take a look at the closure compiler again.
It has 3 execution levels
Whitespace only You used this setting. Just redundant whitespaces are removed.
Simple In addition to removing whitespaces this renames your variables and function names to shorten the overall scripts, but leave your code intact.
Advanced This further improves the simple setting by possible restructuring your code. So, e.g., some functions may get inlined etc.
Closure is a good minifier. Also there are other minifiers worth to check,
Packer: http://dean.edwards.name/packer/
JSMin: http://crockford.com/javascript/jsmin
Related
I want to minimize the size of the Javascript code I have to send over the wire for my personal website. Are there any tricks to writing code that will compress better? I'm thinking about both min-ification and gzip.
Do I need to use short variable names? Or can min-ification just find all instances of those and shorten them? Or is it fine because gzip will detect them and compress over the wire? For functions, is it better to pass in an object with properties? Or just have individual parameters for each value needed? (I can imagine that parameters would be safe for min-ification to shorten because they are always local to the function)
I have a cursory understanding of what these tools do, but it's not enough to be confident in how I should write my Javascript to compress as small as possible.
If you are using a minification tool, you don't need to use short names for your variables, the minifier will take care of that.
As for function arguments, from a minification point of view, it's better to use individual parameters instead of object properties, because the minifier can't rename object properties, but will rename the parameters.
I don't feel qualified to advise you on how to write more compressable code from a Gzip point of view, but I can give you some advice on writing more minifiable Javascript code.
My first advice is that you run your favorite minifier on your code and then compare the pretty printed version of it, with the original code. That way you will learn what kind of changes your minifier makes on your code.
Usually, minifiers rename variables an function names to shorter ones, but can't rename object properties.
So avoid this:
foo.bar.baz.A = 1;
foo.bar.baz.B = 2;
foo.bar.baz.C = 3;
And instead, do this:
var shortcut = foo.bar.baz;
shortcut.d = 1;
shortcut.e = 2;
shortcut.f = 3;
A minifier will rename shortcut to a one or two letters variable.
Another good practice is using method chaining as much as possible (specially if you are using JQuery)
For example, avoid this:
$div.css('background', 'blue'); // set BG
$div.height(100); // set height
$div.fadeIn(200); // show element
And do this instead:
$('#my-div')
.css('background', 'blue')
.height(100)
.fadeIn(200);
You should use both minification and gzipping, see https://css-tricks.com/the-difference-between-minification-and-gzipping/ for some results.
You should also consider using client side caching, as this will eliminate over the wire cost altogether on cache hits.
Also make sure you're not sending any redundant http headers on your response.
I don't know whether there is a solution to this issue, but I have a large set of Javascript functions bearing long descriptive names, something like:
function getTimeFromTimezoneInMilliseconds(...) { ... };
function computeDifferenceFromUTCInMilliseconds(...) { ... };
...
These long names help explaining what the code does, since some operations are complex and not obvious to understand when reading the code only. It helps maintaining the code too.
I am minimifying this Javascript code, but of course, those names are not minimified.
Is there a refactoring trick in Javascript that would allow minimifiers to pick smaller function names and reduce the code size?
You should wrap your code in an IIFE.
This way, you won't have any public members at all, and the minifier will be able to do whatever it wants.
This has the added advantage of not polluting the global scope.
Don't minify yourself! Let the machine do the hard parts.
There are many different options.
You can use an online site where you paste your code and you get the minified back (manual).
You can automate and use a server-side language to minify your JavaScript.
You can use Google CC or Yahoo YUI Compressor to minify and greatly optimize your code.
I need to modify WebDriverJS for my purposes. The compiled source is giving me a hard time debugging, though. Describing function names and comments would help me out big time! So I was wondering whether it is possible to compile WebDriverJS without minimizing it's content.
The build.desc for the JavaScript compilation is using js_binary which is using Google Closure Compiler. Anyone of you know how to compile it and preserve functionnames and comments? This would rather be a merge of all sources then a compilation.
Thanks to Chads Post in "Potential differences between compiled and uncompiled Javascript" I've taken a deeper look at the flags of closure compiler.
--compilation_level=WHITESPACE_ONLY preserves function and variable names
--formatting=PRETTY_PRINT doesn't remove linebreaks
--formatting=PRINT_INPUT_DELIMETER gives me a better overview in which file to search for the source
Unfortunately I still couldn't figure out how to save the comments, but thats just a small problem since I can look them up in the source code.
Update:
Seems like the compilation_level doesn't remove the goog.required-calls. I've got to remove them somehow, because the script doesn't work with them.
Update 2:
I've removed all goog.require($mod) and goog.provide($mod) calls and defined Objects where needed (typically to find right after the // Input $int comments). It's working now.
Now, I've heard of javascript compressors, used a bunch and favour a few. However, they all do the same thing. Remove unnecessary space. That's great, they do exactly what it says on the tin. Compresses Javascript. However, looking through some of the major players that provide legendary libraries (such as jQuery), they offer "minified" sources that are entirely unreadable. Notably, the variable names change from someThingLikeThis to c. This is compression that I cannot seem to find anywhere.
My question is, where can I find a Javascript compressor which compresses variables in addition to removing unnecessary space. Or is it done manually?
For example:
// My Javascript:;
var cats = 'Nyan',
dogs = 'Hound';
alert(cats + dogs);
// jQuery styled compression:
var a='Nyan',b='Hound';alert(a+b);
As far as i know http://developer.yahoo.com/yui/compressor/ Does what you need :)
That should be done by a standard minifier. If it is not, then most likely the variable names just cannot be renamed safely (global variables/functions).
Also what you might be looking for is obfuscator. Check this question:
How can I obfuscate (protect) JavaScript?
Google Closure Compiler is the most advanced tool to transpile/minify JavaScript code.
It basically features two compilation levels—simple and advanced. You can use the simple compilation level on pretty much any JS code.
The true magic is in the advanced level which removes unused code, inlines functions, flattens properties (abc.def.ghi -> a) and renames all custom variables. But you have to write the code in a way the compiler can understand.
If you're serious about JS, read the "Closure: The Definitive Guide" by Michael Bolin who is one of the lead developers of the Closure Tools.
My project seems to be getting bigger and bigger and some of my classes are thousands of lines long. It's too hard to search through them every time I want to make changes.
I find JavaScript is not as easy to lay out cleanly as some other programming languages. So when the classes get to be a few thousand lines, I have troubles reading it.
I've tried splitting it into multiple files, but then you're breaking classes apart, which doesn't seem right. For example, if every method in a class uses a global variable, you would only be able to find the global variable in one of the files for that class.
Also, if I want to use the JavaScript code from 100 different .js files, I end up with something like this...
<script type="text/javascript" src="Scripts/classes/Node.js"></script>
<script type="text/javascript" src="Scripts/classes/Queue.js"></script>
<script type="text/javascript" src="Scripts/classes/DblyLinkedList.js"></script>
.... 97 more lines like this
Although, I figured there may be something where I can do...
<script type="text/javascript" src="Scripts/.../*.js"></script>
or something similar... is that right?
Anyone have any tips on managing code as it reaches its extremes?
Tips on cleaning up JavaScript code would also be helpful.
Breaking up JS into separate files has some major drawbacks, chiefly that you're forcing web browsers to make a separate request for each file.
Have you taken a look at leaving all of your files separated out, but making a single-file "bundle" for each project containing only the necessary files? This can be automated via a script.
This SitePoint article might help you get started: http://www.sitepoint.com/blogs/2007/04/10/faster-page-loads-bundle-your-css-and-javascript/
(a) keep your classes shorter [even
though that will mean yet more
files],
(b) keep them "full-text
indexed" for speed of search and
operation (not aware of any IDE
specifically supporting Javascript
this way, but strong editors like
Emacs, Vim, Eclipse, or TextMate sure
do),
(c) group them up hierarchically
so your pages can have just a few
<script> tags for "upper layer"
scripts each of which just pulls in
several of the "lower layer" ones.
Oh, and, of course, religiously keep everything under a good change control system (SVN, Mercurial, or the like), otherwise your life will be surely very very miserable:-(.
You might want to group related classes together into packages, where each package is a single file. Check out YSlow for best practices on performance.
Well, a good editor is always usefull, as it will give you shortcuts to all your functions defined in the files.
Second, make sure you're not looking at a wall of code. Indentation, spaces and newlines are a good help.
Be extremely strict in your indentation. 2 spaces is 2 spaces, always(or whatever amount you use)
if you put your { under a declaration, then always put it there, without exception)
Clear rules about how you want your text aligned will help a lot.
And I don't know about that last thing... I'm not sure browsers can work with that kind of wildcard.
<script type="text/javascript" src="Scripts/.../*.js"></script>
will not work, and besides, you end up with an interesting problem when splitting up dependent files, as you can't guarantee they will all be downloaded in the order you expected.
Unfortunately, your best bet is really a good IDE that can produce an outline for easy navigation. I use Eclipse with Spket and/or Aptana, but whatever makes it easier to manage is what you're looking for.
edit: one more quick note about splitting js into multiple files. Avoid it where possible. Each separate file means a separate http request. Reducing the number of requests required can make a massive difference in site performance.
AvatarKava's advice is sound. Work in separate files and concatenate them at build time. However, I would also recommend you take a look at your class structure. A class "thousands of lines long" doesn't sound too healthy. Are you sure you classes aren't taking on too much responsibility? Are there not tasks that can be shipped out to other single responsibility classes? This would help improve the clarity in your code far more than cunning ways of splitting files.
Same advice applies to most languages...
Avoid globals wherever possible. You can often get the desired behavior by wrapping a static variable, or using objects.
if (foo == undefined)
var foo
Use naming conventions where possible so you can track things down just by reading the variable or function names. Either that or get good with grep, or get an IDE with intellisense.
Split things into directories. Having 100 files in a directory called "classes" is not helpful. As an example, you may have a collections directory for queues, lists, trees, etc. If you've got a lot you may even have a tree subdir, or a list subdir, etc.
You can then also create a global include for that directory... simply a file called collections.js that includes all of the files in that directory. Of course you have to be careful about splitting things up well, since you don't want to be including files you'll never use.