Missouri State University

Skip to content Skip to navigation
a b c d e f g h i j k l m n o p q r s t u v w x y z

Web Strategy and Development Blog

  • Web Strategy and Development
  • Web Support
  • @msuweb

Closure Compiler: Which Compilation Level is Right for Me?

When first starting with Closure Compiler, it is easy to see the names for the compilation levels and assume that advanced is better than simple. While it is true that advanced optimization generally produces a smaller file, that does not mean it is the best fit for all projects.

September 26, 2012 by Web Strategy and Development

Share this post:

  • Twitter
  • Facebook
  • LinkedIn
  • Pinterest
  • Pocket
  • Tumblr
  • Email

Cross posted to the Closure Tools Blog

When first starting with Closure Compiler, it is easy to see the names for the compilation levels and assume that advanced is better than simple. While it is true that advanced optimization generally produces a smaller file, that does not mean it is the best fit for all projects.

What is really the difference?

There are quite a few differences, but the most significant is dead-code elimination. With advanced optimizations the compiler removes any code that it knows you are not using. Perfect! Who would not want that? Turns out a lot of people because the compiler can only correctly eliminate code when you specifically tell it about ALL of the other code used in your project AND ALL of the ways that your code is used by other scripts. Everything should be compiled together at the same time. That is a pretty big gotcha.

Here is a classic example:

<html>
<head>
  <title>Advanced Optimization Gotchas</title>
  <!-- an external library -->
  <script src="jquery-1.7.2.js"></script>
  <script>
    //This section is compiled
    function ChangeBackground() {
      $('body').css('background-color', 'pink');
    }
    //Export for external use
    window['ChangeBackground'] = ChangeBackground;
  </script>
</head>
<body>
  <!-- external use of compiled code -->
  <a onclick="ChangeBackground()">Pinkify</a>
</body>
</html>

<html> <head> <title>Advanced Optimization Gotchas</title> <!-- an external library --> <script src="jquery-1.7.2.js"></script> <script> //This section is compiled function ChangeBackground() { $('body').css('background-color', 'pink'); } //Export for external use window['ChangeBackground'] = ChangeBackground; </script> </head> <body> <!-- external use of compiled code --> <a onclick="ChangeBackground()">Pinkify</a> </body> </html>

In this case we have to explicitly tell the compiler about jQuery during compilation with an extern file and we have to tell it that our ChangeBackground function is called from external code. While this is a contrived example, it illustrates a case where it probably was not worth the time to ensure compatibility with the advanced optimization level.

General decision factors

So how do you actually decide which optimization level is right for your project? Below are some of the most common factors in that decision:

Simple Optimizations Advanced Optimizations
Looking for a replacement JavaScript compressor Looking for every last byte of savings in delivered code size or in execution time
Compiling a library where the vast majority of functions are part of the publicly exposed API Authoring a very large application with multiple modules
Unwilling to make substantial changes to code style Starting a new project or are willing to make substantial changes to coding style and patterns
Using external libraries that do not have existing extern files and are not compatible with advanced optimizations Wanting the best possible obfuscation of your code to protect intellectual property
On a tight timeline that does not allow for troubleshooting obscure errors after compilation Authoring a large library but want to support users who only use a small subset of the code

Coding style factors

Most of us are proud of our JavaScript. In fact we may have some slick coding patterns that make our code elegant to read and maintain, however, not all JavaScript coding patterns compile equally with Closure Compiler advanced optimizations. If your code contains any of the following (and you are unwilling to change this) then simple optimizations would probably be the best choice for you:

  • Mixed property access methods
    Closure Compiler treats properties accessed with dotted notation (obj.prop) differently than when accessed via brackets or quoted notation (obj[‘prop’]). In fact it sees them as completely different properties. This item is first on the list for a reason: it is almost always the biggest hurdle. Because of this, the following patterns are all places which can cause problems with advanced optimizations:

    1. Building method names with strings
      var name = 'replace';
      obj[name] = function() {};
      obj[name + 'With'] = function() {};
      Obj.replaceWith(); //Mixed access problem

      var name = 'replace'; obj[name] = function() {}; obj[name + 'With'] = function() {}; Obj.replaceWith(); //Mixed access problem

    2. Testing for property existence with strings
      obj.prop = 'exists';
      if ('prop' in obj) … //Mixed access problem

      obj.prop = 'exists'; if ('prop' in obj) … //Mixed access problem

    3. Using a property name in a loop
      obj.prop = function() {};
      for (var propName in obj) {
        if(propName == 'prop') { //Mixed access problem
        }
      }

      obj.prop = function() {}; for (var propName in obj) { if(propName == 'prop') { //Mixed access problem } }

  • Using the “this” keyword outside of constructors or prototype methods
    var obj = {};
    //Static method using “this”
    obj.prop = function() { this.newprop = 'exists' };
    obj.prop();
    alert(obj.newprop);
    ...

    var obj = {}; //Static method using “this” obj.prop = function() { this.newprop = 'exists' }; obj.prop(); alert(obj.newprop); ...

    In advanced optimizations, Closure Compiler can move and refactor code in unexpected ways. Some of them include functions which are inlined and properties which are collapsed to variables. In many of these cases, it changes which object the “this” keyword references. These cases have workarounds, but without special attention your code will likely not execute as intended. To illustrate, under advanced optimizations the compiler might change the above code to:

    var obj = {};
    var a = function() { this.newprop = 'exists' };
    a();
    //Property does not exist - it is defined on the window object
    alert(obj.newprop);

    var obj = {}; var a = function() { this.newprop = 'exists' }; a(); //Property does not exist - it is defined on the window object alert(obj.newprop);

Choose wisely

Regardless of the choice between simple or advanced optimizations, you can still use the many compile time code checks and warnings for your code. From a missing semicolon to a misspelled property, the compiler can assist in identifying problems with your code before your users do it for you.

So to recap, advanced is not always better than simple. Modifying an existing code base to be compatible with Closure Compiler advanced optimizations can be a daunting challenge, and it definitely is not the best choice for every project.

  • About the Author
  • Latest Posts

About Web Strategy and Development

  • Recap: Hello Omni CMS, goodbye Web Press! - March 14, 2023
  • Improve your Omni CMS skills at this free training - February 21, 2023
  • Celebrate Global Accessibility Awareness Day (GAAD) on May 19 - May 16, 2022
  • New Content Management System Coming Soon - March 3, 2021
  • Meet our newest team member: Valerie Cummings - October 20, 2020
  • Graduate students: Share the stories of MSU - May 1, 2019
  • New design for university websites - April 17, 2019
  • Marketing and communications offices have new names - July 6, 2018
  • Social Media Kit: Spring 2018 Public Affairs Conference - March 27, 2018
  • Lessons learned from the Alumni Association and Bear Bulletin redesigns - March 2, 2018

Filed Under: Technical, web strategy and development Tagged With: javascript

Share this post:

  • Twitter
  • Facebook
  • LinkedIn
  • Pinterest
  • Pocket
  • Tumblr
  • Email

Subscribe

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Follow @MSUWeb

My Tweets

Calendar

  • Complete Calendar

Categories

  • Accessibility
  • brand
  • email marketing
  • Mobile
  • News
  • Omni CMS
  • Redesign
    • Academic websites
    • Web redesign 2015
  • Social media
    • Social media kit
  • template
    • updates
  • Training
  • Video
  • Web Press
  • web strategy and development
    • Technical
  • Web Support
  • WordPress blogs

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Connect with web strategy and development

  • Twitter

Make your Missouri statementMake your Missouri statement
  • Last Modified: July 2, 2018
  • Accessibility
  • Disclaimer
  • Disclosures
  • EO/AA/M/F/Veterans/Disability/Sexual Orientation/Gender Identity
  • © 2013 Board of Governors, Missouri State University
  • Contact Information
loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.
 

Loading Comments...