YUI Compressor Version 2.1 Now Available

This new version of the compressor fixes a few bugs and optimizes string concatenations. You can now keep your code nicely formatted by concatenating string literals, but not suffer any performance hit. For example, the following code:

var url = "http://www.flickr.com/services/rest/"
    + "?method=flickr.test.echo"
    + "&format=json"
    + "&api_key=02b6a73df2c4a33c282f3d02fe5724e3"
    + "&callback=jsonCallback";

will become ( marks a line continuation)

var url = "http://www.flickr.com/services/rest/
?method=flickr.test.echo&format=json
&api_key=02b6a73df2c4a33c282f3d02fe5724e3&callback=jsonCallback";

Also, note that, from now on, all YUI Compressor-related downloads will be done from a separate download page and not directly from this blog.

Download version 2.1 of the YUI Compressor

29 thoughts on “YUI Compressor Version 2.1 Now Available

  1. Pingback: Ajax Performance » Quick follow-up: more YUI Compressor work

  2. Pingback: CompressorRater: Compare the squeeze « outaTiME

  3. The Doctor What

    Julien Lecomte:

    Thanks again for your work on this. It is excellent.

    In your comment on the 2.0 page, you mention two of my suggestions and the bug that you had already fixed in 2.1.

    I have no problem not having the multiple filenames.

    I think that accepting STDIN and STDOUT for the file arguments would be a big help. It would also make not having multiple filenames no big deal.

    And line numbers for the warnings would be very useful. :-)

    Thanks again!

  4. Pingback: Ajax Girl » Blog Archive » CompressorRater: Compare the squeeze

  5. John Kloor

    In the CSS compressor, you made this change “Remove spaces before and after ‘(‘ and ‘)’ as in background:url(‘xxx’);”.

    But, when I have a “background:url(‘xxx’) no-repeat;” the space before “no-repeat” is removed. This prevents the background from appearing in Internet Explorer.

  6. Pingback: YUI Compressor 2.1 Released » Chris Norton

  7. Pingback: Ajaxian » CompressorRater: Compare the squeeze

  8. Fredrik

    Probably a slightly stupid question but anyway:
    How hard would it be to have the compressor attack JS-namespaces and method-names? I find quite a portion of my code to be consisting of,”MyCompany.NamesSpaceOne.myFunction” stuff..

    I’m feeling there’s a catch here, or?

  9. Julien Lecomte Post author

    @Fredrik

    Yes, there is a catch (of course!) Prior to developing the YUI Compressor, I worked (in another company) on a compressor that was able to do just that: obfuscate everything! However, to accomplish that, we had to introduce all types of “hints” to tell the compressor the type of each variable, etc. The problem here can be summarized by the term “COST EFFICIENCY”: you want to get the biggest bang for your buck. If you need to spend many extra cycles debugging because you want to save an additional 10%, you are not taking the most efficient approach. Trust my experience!

  10. David Bernard

    Hi,
    Is it possible to add (in a next version, no urgence) an option to keep header comments (if it contains “license” or “copyright” or “(c)”, to agree Copyrigth/Open Source license.

  11. Julien Lecomte Post author

    @David Bernard

    This type of task is beyond the scope of the compressor. If you need to prepend some license or copyright information, use the cat command line utility, or if you use Apache Ant to build your application, use a nested header element to the concat task.

    Regards

  12. Elliott Back

    @David, just because your application has to carry the license doesn’t mean you have to put it in your .css file…

    Julien, nice working on the string-concatenation constant folding case. When do we get generic constant propagation? :D

  13. David Bernard

    I requested the feature for third parties js and css files, with various licenses.
    Some licenses require keep it and credit authors, eg :
    “The collection is dual licensed with the MIT license and the GPL, which basically means you can use it for free for both non-commercial and commercial usage as long as you keep the copyright notice in each of Interface’s JavaScript source file.”
    from interface elements for jQuery.

    But may be, “minified” files could be considered like compiled ones.

    Thanks for the replies.

  14. Fredrik

    @Julien
    Ok, I do trust you. One of the major reasons I’m interested in, and have tried out your compressor, is the safety-factor. Only JsMin has previously handled our code without errors (and I’m not doing any evals withs..).
    Though, the reason I pondered namespace & function mangling was that I kindof suspect the savings to be quit a bit larger than 10%. I guess I need to write some test..
    Perhaps an option? –alias MyNamespace MN ?

  15. Jason Collins

    Very nice, thanks for the update! Has anyone integrated this into an ANT task yet and if so, could you please explain how you did it or send me an example? Thanks.

  16. chris holland

    Merci pour ce composant genial, je ne l’ai pas encore integre’ dans mon projet, mais ca ne saurait tarder, il me suffira juste de remplacer shrinksafe. Pour que ca marche pour moi il me faudra acceder a l’API Java, je suppose que javaScriptCompressorInstance.compress devrait faire l’affaire.

  17. The Doctor What

    Create a file called test.js with the following contents:

    /*extern YAHOO, viv */
    /*jslint undef: false, nomen: true, evil: false, undef: true, browser:
    true, white: true */

    (function () {
    viv.example = function () {
    };

    viv.example();

    YAHOO.example = function () {
    };

    YAHOO.example();
    })();

    Then execute yuicompressor like so and notice the WARNING.

    $ bin/yuicompressor –charset utf-8 –warn test.js

    [WARNING] Found an undeclared symbol: viv
    (function (){viv —> .

    This is strange. It didn’t complain about YAHOO, but complained about
    viv. It’s almost as if someone added YAHOO to an exception list… ^_^

    It should either complain about both or neither.

    Alternatively, it could honor jslint’s extern declaration, which I’d
    like even better.

    Ciao!

  18. Julien Lecomte Post author

    @The Doctor What

    Since all local variables are going to be renamed to a 1 (or 2, or 3) letter symbol, it tries to spot undeclared globals that are less then 3 letters in length (which is the case for “viv”) to avoid naming conflicts, and shows a warning. It does not care about undeclared globals that are 4 letters long or more (which is the case for “YAHOO”)

    I am planning to make some improvements in that area.

    Regards

  19. The Doctor What

    Oh, okay. That makes sense. Obviously, knowing what variable names it can and cannot use would be better. Meanwhile, can you clean up the warning to say something like your message above?

    Can’t you just have a function to generate the identifiers for you? Something like (in JavaScript, because I don’t do enough Java to be confortable):

    var idengen = function () {
    if (typeof (idengen.list) === ‘undefined’) {
    idengen.init();
    }
    var count = 0;
    var next = this.gen();
    while (count

    Then if you find an undefined global variable, then just call idengen.seen(globalvar);.

    Now that I think about it, it would be helpful to track all undifined global variables and then return them optionally with a command line param.

    Ciao!

  20. Kezzel

    Hi Julien

    I’m building a website framework using js-compressors, and have come accross a problem that I can not find an answer for anywhere else. It seems like you are close to the guru in this area and thus I turn my hope for an answer to you.

    The goal of the framework is to allow modules to be loaded on the fly, either in the background after the initial load has been done, or when the user requests an action/functionality that has not yet been used. When compressing I hide all unnecessary names by enclosing the total script in an anonymous function. This however obfuscates the names in the base js and the modules in different environments and thus they cannot use eachother. My question is thus if it is possible with the current compressors to set a starting obfuscation table of name=>obfuscated_name when compressing a new file and thus compress it like it was compressed in that environment? Using this approach compressed modules could be run inside the compressed environment by using eval.

    Best regards
    Kezzel

  21. Julien Lecomte Post author

    @Kezzel

    Each module should export a set of global symbols. Simply omit the ‘var’ keyword in front of them, and they won’t obfuscated.

    Hope this helps,
    Julien

Comments are closed.