Extreme JavaScript Compression With YUI Compressor
-
Upload
nicholas-zakas -
Category
Business
-
view
29.050 -
download
1
description
Transcript of Extreme JavaScript Compression With YUI Compressor
Extreme JavaScript Compression with YUI Compressor
Nicholas C. ZakasPrincipal Front End Engineer, Yahoo!
Who's this guy?• Principal Front End Engineer, Yahoo! Front Page
• YUI Contributor• Author
JavaScript Minification/Compression
• Problem: Lots of JavaScript• Solution: Make JavaScript smaller• Two areas:
– Wire weight– Browser weight
Server
Wire Weight Solution: Gzip
Internet
Browser
Wire Weight Solution: Gzip
Internet
Browser Weight
Browser Weight Solution: Minification• Remove comments• Remove extra white space• Identifier replacement• Other...
Minification Tools• ECMAScript Cruncher (ESC)
– http://www.saltstorm.net/depo/esc/• JSMin
– http://www.crockford.com/javascript/jsmin.html• Packer
– http://dean.edwards.name/packer/• Dojo Shrinksafe
– http://shrinksafe.dojotoolkit.org/
YUI Compressor
http://developer.yahoo.com/yui/compressor/
About YUI Compressor• Remove comments• Remove extra white space• Identifier replacement• Micro-optimizations• Built on top of Rhino interpreter
– Makes all optimizations safe
Mozilla Rhino
• Open source JavaScript interpreter• Written in Java• Based on Firefox's interpreter
http://www.mozilla.org/rhino/
How It Works
Micro Optimizations
The Results
-44%
-44%
Helping the Compressor
Best Optimization=
Identifier Replacement(aka munging)
Identifier Replacement• Local identifiers only
– Functions and variables
What Can't Be Replaced• Primitive values
– strings, booleans, numbers, null, and undefined
Primitive Values• Strings take up the most space• Non-numeric literals take second-most
– true, false– null– undefined
• Approach: Any literal value used two or more times should be stored in a local variable
Primitive Values
263 b
172 b
Primitive Values
293 b
162 b
Prototype• 79 repeated strings = 1196 bytes• 80 true/false = 359 bytes• 44 null = 176 bytes• 21 undefined = 189 bytes• Total primitives = 1920 bytes• Potential savings > 1 kb
jQuery• 96 repeated strings = 1742 bytes• 107 true/false = 478 bytes• 46 null = 184 bytes• Total primitives = 2404 bytes• Potential savings > 1.3 kb• undefined = negligible
jQuery
Primitive Variables
What Can't Be Replaced• Primitive values
– strings, booleans, numbers, null, and undefined• Global variables
– window, document, XMLHttpRequest, etc.
Global Variables• Most bytes:
– document– window
• Approach: Any global variable used two or more times should be stored into a local variable
Global Variables
293 b
162 b
Global Variables
317 b
162 b
Prototype• 49 document = 392 bytes• 29 window = 174 bytes• Total globals = 566 bytes• Potential Savings > 500 bytes
jQuery• 24 document = 192 bytes• 27 window = 162 bytes• Total globals = 354 bytes• Potential Savings > 300 bytes
What Can't Be Replaced• Primitive values
– strings, booleans, numbers, null, and undefined• Global variables
– window, document, XMLHttpRequest, etc.• Property names
– foo.bar
Property Names• Next to repeated strings, biggest source of extra
bytes• Anything to the right of a dot cannot be replaced• Makes a.b.c even more expensive• Approach: Any property used two or more times
should be stored into a local variable
Property Names
317 b
162 b
Property Names
291 b
144 b
What Can't Be Replaced• Primitive values
– strings, booleans, numbers, null, and undefined• Global variables
– window, document, XMLHttpRequest, etc.• Property names
– foo.bar• Keywords
Keywords• Most commonly overused:
– var– return
• Approach: Try to have only one var statement and one return per function
Keywords
291 b
144 b
Keywords
308 b
127 b
The Results
127 b
172 b
Before:
After:
Total Savings (from original) = 136 b (52%)Total Savings (from final) = 181 b (59%)
Hurting the Compressor
Preventing Identifier Replacement• Use of eval() function
“eval() is evil”-Douglas Crockford
eval() is Evil
eval() is Evil
Preventing Identifier Replacement• Use of eval() function
– Solution #1: Don't use it– Solution #2: Create a global function that wraps eval()
Living with eval()
Preventing Identifier Replacement• Use of eval() function
– Solution #1: Don't use– Solution #2: Create a global function that wraps eval()
• Use of with statement
“with statement considered harmful”-Douglas Crockford
with Statement
Preventing Identifier Replacement• Use of eval() function
– Solution #1: Don't use– Solution #2: Create a global function that wraps eval()
• Use of with statement– Solution #1: Don't use– Solution #2: see Solution #1
Preventing Identifier Replacement• Use of eval() function
– Solution #1: Don't use– Solution #2: Create a global function that wraps eval()
• Use of with statement– Solution #1: Don't use– Solution #2: see Solution #1
• JScript conditional comments
Jscript Conditional Comments
Preventing Identifier Replacement• Use of eval() function
– Solution #1: Don't use– Solution #2: Create a global function that wraps eval()
• Use of with statement– Solution #1: Don't use– Solution #2: see Solution #1
• JScript conditional comments– Only solution: Don't use
The Compressor Helps You
Verbose Mode• Use -v switch to enable• Reports issues with code related to minification:
– Undeclared variables– Unused variables– Functions with more than one var statement– Use of evil features (eval(), with, conditional
comments)
Verbose Mode
Summary
For Optimal File Size• Use local variables to store:
– Repeated primitive values– Global variables– Object properties
• Limit each function to one var and one return
• Avoid using eval() and with()• Heed YUI Compressor's advice• Combine with HTTP compression for best savings
http://developer.yahoo.com/yui/compressor/
Questions?
Etcetera
• My blog: www.nczonline.net• My email: [email protected]• Twitter: @slicknet
Happy crunching!
Creative Commons Images Used• http://flickr.com/photos/velkr0/467471030/• http://flickr.com/photos/oskay/253010234/• http://flickr.com/photos/pacfolly/2304020816/• http://flickr.com/photos/blmurch/304690615/• http://flickr.com/photos/tshirbert/191179745/• http://flickr.com/photos/mc/27061495/• http://flickr.com/photos/oberazzi/318947873/