Minify JavaScript

Configuration

The 'Minify JavaScript' filter is enabled by specifying:

Apache:
ModPagespeedEnableFilters rewrite_javascript
Nginx:
pagespeed EnableFilters rewrite_javascript;

in the configuration file.

Note: New feature as of 1.9.32.1

rewrite_javascript is equivalent to enabling both rewrite_javascript_inline and rewrite_javascript_external. The former rewrites only inline scripts, and the latter rewrites only external ones.

New Minification Parser

We introduced a new minification parser in version 1.8.31.2 that improves on some of the shortcomings of the previous parser (for example, correct tokenizing of regular expressions). As of 1.10.33.0, the new parser is used by default, but you can revert back to the old parser with this configuration flag:

Apache
ModPagespeedUseExperimentalJsMinifier off
Nginx
pagespeed UseExperimentalJsMinifier off;

Before 1.10.33.0, the old minification parser was used by default. You can enable the new minification parser with:

Apache
ModPagespeedUseExperimentalJsMinifier on
Nginx
pagespeed UseExperimentalJsMinifier on;

If you have configured any custom javascript libraries for canonicalization you'll have to regenerate your signatures with both --use_experimental_minifier (for the new minifier) and --nouse_experimental_minifier (for the old minifier) flags.

Description

This filter minifies JavaScript code, using an algorithm similar to that in Douglas Crockford's popular JSMin program. At present, the filter strips all comments and most whitespace. The filter works only on JavaScript found in <script> blocks (either as the target of the src attribute, or within the body of the block).

Minification can drastically reduce the byte count in common JavaScript code. This filter can be used to avoid the extra step of minifying Java code by hand when constructing and maintaining a site.

This practice reduces the payload size.

Operation

The 'Minify JavaScript' filter removes unnecessary bytes on the wire. While it's great to put comments, tabs and whitespace in code to improve readability and maintenance, these are bytes that take up space on the wire and that a browser's JavaScript parser has to parse unnecessarily.

For example, if the HTML document looks like this:

<html>
  <head>
  </head>
  <body>
    <script>
      // This comment will be removed
      document.write("Howdy");
      state = 1
    </script>
    <script src="extScript.js" type="text/javascript">
    </script>
    <script src="extScript1.js">
    /* Note that the contents of a script block aren't altered
       if a src is specified.  It is assumed the code will be
       using the script block contents as data. */
    document.write("Internal script; state = " + state);
    state = 42
  </script>
  </body>
</html>

With the following in extScript.js:

  /* Inject state into document */
  document.write("External " + state);
  state += 1;  // Then update it.

Then PageSpeed will rewrite it into:

<html>
  <head>
  </head>
  <body>
    <script>document.write("Howdy");state=1</script>
    <script src=".../extScript.js.pagespeed.jm.HASH.js"></script>
    <script src=".../extScript1.js.pagespeed.jm.HASH.js" type="text/javascript">
    /* Note that the contents of a script block aren't altered
       if a src is specified.  It is assumed the code will be
       using the script block contents as data. */
    document.write("Internal script; state = " + state);
    state = 42
  </script>
  </body>
</html>

And the rewritten file extScript.js.pagespeed.jm.HASH.js will contain:

document.write("External "+state);state+=1;

Example

You can see the filter in action at www.modpagespeed.com on this example.

Requirements

Only JavaScript code referenced by <script> tags is rewritten. Code fragments that occur elsewhere (for example event handler declarations in CSS) are not altered.

Risks

Some JavaScript code depends upon the formatting of scripts in the page. For example, scripts exist that store data in JavaScript comments, then walk the DOM, retrieve the source code for the script, and read the data from the comments. This will not work in conjunction with any minification tool. Authors are encouraged instead to store data either in the body of a script with a src (as shown in the example above), in hidden <div> or <span> elements in the page itself, or best of all in JavaScript string constants.

This filter is sensitive to AvoidRenamingIntrospectiveJavascript. For example, a JavaScript file that calls document.getElementsByTagName('script') will not be rewritten.