用 YUI Compressor 壓縮和混淆 JS 和 CSS

來源:互聯網
上載者:User

   一、簡介:

    目前開發Web應用Javascript發揮的作用越來越大,相關的Javascript架構也比較多。但是有一個問題,我們開發過程中,所有的JS代碼都添加了注釋,如使用JsDoc,代碼的可讀性比較強,同時這樣的代碼也便於調試。但是在產品環境中,我們希望這些JS代碼是壓縮和混淆過的,這主要是讓 JS代碼載入的更快,這也是Google AJAX Libraries API出現的原因。YUI Compressor 是一款由 Yahoo 公司開發的、功能非常強大的 JS、CSS 代碼混淆和壓縮公用程式,採用Java開發,目前很多Javascript Framework都使用YUI Compressor進行代碼分發。

    YUI Compressor 官網網址:
    http://developer.yahoo.com/yui/compressor/

    YUI Compressor 下載頁面:
    http://yuilibrary.com/downloads/#yuicompressor

分流:pasting 

    二、使用簡介:

    在命令列下執行 Java 程式,運行 yuicompressor jar 軟體包,來完成任務:

    //壓縮JS
    java -jar yuicompressor-2.4.2.jar --type js --charset utf-8 -v src.js > packed.js

    //壓縮CSS
    java -jar yuicompressor-2.4.2.jar --type css --charset utf-8 -v src.css > packed.css

    三、參考官方英文注釋:

    3.1 How does the YUI Compressor work?

    The YUI Compressor is written in Java (requires Java >= 1.4) and relies on Rhino to tokenize the source JavaScript file. It starts by analyzing the source JavaScript file to understand how it is structured. It then prints out the token stream, omitting as many white space characters as possible, and replacing all local symbols by a 1 (or 2, or 3) letter symbol wherever such a substitution is appropriate (in the face of evil features such as eval or with, the YUI Compressor takes a defensive approach by not obfuscating any of the scopes containing the evil statement) The CSS compression algorithm uses a set of finely tuned regular expressions to compress the source CSS file. The YUI Compressor is open-source, so don't hesitate to look at the code to understand exactly how it works.

    3.2 Using the YUI Compressor from the command line

    java -jar yuicompressor-x.y.z.jar

    Usage: java -jar yuicompressor-x.y.z.jar [options] [input file]

    Global Options
      -h, --help                Displays this information
      --type <js|css>           Specifies the type of the input file
      --charset <charset>       Read the input file using <charset>
      --line-break <column>     Insert a line break after the specified column number
      -v, --verbose             Display informational messages and warnings
      -o <file>                 Place the output into <file>. Defaults to stdout.

    JavaScript Options
      --nomunge                 Minify only, do not obfuscate
      --preserve-semi           Preserve all semicolons
      --disable-optimizations   Disable all micro optimizations

    GLOBAL OPTIONS

    -h, --help
        Prints help on how to use the YUI Compressor

    --line-break
        Some source control tools don't like files containing lines longer than,
        say 8000 characters. The linebreak option is used in that case to split
        long lines after a specific column. It can also be used to make the code
        more readable, easier to debug (especially with the MS Script Debugger)
        Specify 0 to get a line break after each semi-colon in JavaScript, and
        after each rule in CSS.

    --type js|css
        The type of compressor (JavaScript or CSS) is chosen based on the
        extension of the input file name (.js or .css) This option is required
        if no input file has been specified. Otherwise, this option is only
        required if the input file extension is neither 'js' nor 'css'.

    --charset character-set
        If a supported character set is specified, the YUI Compressor will use it
        to read the input file. Otherwise, it will assume that the platform's
        default character set is being used. The output file is encoded using
        the same character set.  IMPORTANT: if you do not supply this argument
        and the file encoding is not compatible with the system's default
        encoding, the compressor will throw an error.  In particular, if your
        file is encoded in utf-8, you should include this parameter.

    -o outfile
        Place output in file outfile. If not specified, the YUI Compressor will
        default to the standard output, which you can redirect to a file.

    -v, --verbose
        Display informational messages and warnings.

    JAVASCRIPT ONLY OPTIONS

    --nomunge
      Minify only. Do not obfuscate local symbols.

    --preserve-semi
      Preserve unnecessary semicolons (such as right before a '}') This option
      is useful when compressed code has to be run through JSLint (which is the
      case of YUI for example)

    --disable-optimizations
      Disable all the built-in micro optimizations.Note: If no input file is specified, it defaults to stdin.

    The following command line (x.y.z represents the version number):

    java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.jswill minify the file myfile.js and output the file myfile-min.js. For more information on how to use the YUI Compressor, please refer to the documentation included in the archive.

    The charset parameter isn't always required, but the compressor may throw an error if the file's encoding is incompatible with the system's default encoding. In particular, if your file is encoded in utf-8, you should supply the parameter.

    java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js --charset utf-8

    四、YUI Compressor 壓縮 JavaScript 的原理

    YUI Compressor 壓縮 JavaScript 的內容包括:

    1.移除注釋
    2.移除額外的空格
    3.細微最佳化
    4.標識符替換(Identifier Replacement)

    YUI Compressor 包括哪些細微最佳化呢?

    • object["property"],如果屬性名稱是合法的 JavaScript 標識符(註:合法的 JavaScript 標識符——由一個字母開頭,其後選擇性地加上一個或者多個字母、數字或底線)且不是保留字,將最佳化為: object.property
    • {"property":123},如果屬性名稱是合法的 JavaScript 標識符且不是保留字,將最佳化為 {property:123} (註:在對象字面量中,如果屬性名稱是一個合法的 JavaScript 標識符且不是保留字,並不強制要求用引號引住屬性名稱)。
    • 'abcd/'efgh',將最佳化為 "abcd'efgh"。
    • "abcd" + "efgh",如果是字串相串連,將最佳化成 "abcdefgh"(註:所有在使用 YUI Compressor 的前提下,對於指令碼中的字串串連,使用串連符 “+” 的效率和可維護性最高)。
    對於 JavaScript 最有效壓縮最佳化,當屬標識符替換。

    比如:

    (function(){function add(num1, num2) {return num1 + num2;}})();

    進行屬標識符替換後:

    (function(){function A(C, B) {return C+ B;}})();

    再移除額外的空格,最終成了:

    (function(){function A(C,B){return C+B;}})();

    YUI Compressor 標識符替換僅替換函數名和變數名,那哪些不能被替代呢?

    1.原始值:字串、布爾值、數字、null 和 undefined。一般來說字串占的空間最多,而非數字字面量其次(true、false,null,underfinded)。
    2.全域變數:window、document、XMLHttpRequest等等。使用最多的就是 document、window。
    3.屬性名稱,比如:foo.bar。佔據的空間僅次於字串,”.” 操作符無法被代替,且 a.b.c 更加費空間。
    4.關鍵字。經常被過度使用的關鍵字有:var、return。最好的最佳化方法:一個函數僅出現一次 var 和 return 關鍵字。
    對於原始值、全域變數、屬性名稱的最佳化處理方式大致相同:任何字面量值、全域變數或者屬性名稱被使用超過 2 次(包括2次),都應該用局部變數儲存代替。

    但有部分情況下是禁止使用標識符替換的:

    1.使用 eval() 函數。解決方案:不使用或者建立一個全域函數封裝 eval()。
    2.使用 with 語句。解決方案:方法同上。
    3.JScript 的條件注釋。唯一解決的方法:不使用。
    由於 YUI Compressor 是建立在 rhino interpreter 基礎上的,所以上述所有的最佳化都是安全的。

    五、參考資料:
    《Extreme JavaScript Compression With YUI Compressor》:
    http://www.slideshare.net/nzakas/extreme-javascript-compression-with-yui-compressor

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.