Advertisement

Automated Optimization with HTML5 Boilerplate Build

by

HTML5 Boilerplate is widely recognized as a rock-solid foundation for building new web-based sites and applications. That said, few are aware that the tool offers more than simply setting up your development environment. It also helps you "wrap up" your work by providing an awesome cross-platform build process.


The Build Script, with Paul Irish


Overview

So why might you need this build tool? Because it's baked into HTML5 Boilerplate, and can help you automate web performance optimization. We chose to go with Apache Ant to handle the workload. How come?

All other tools have limitations that Ant's original author couldn't live with when developing software across multiple platforms.

Many developers are unfamiliar with the build process. But don't worry; a build tool isn't a scary monster. Everything can be configured through a relatively simple XML file. This article will help you understand how to set up the build tool, customize the build process and finally change variables and run the build.


The Directory Structure

The build script makes some assumptions about how your files are sorted and structured. Here is the folder structure of HTML5 Boilerplate:

Tutorial image
  • /js/libs/ - contains common script libraries: Modernizr, jQuery and a pngfix for IE6
  • /js/mylibs/ - contains site specific custom library scripts
  • /plugins.js - all jQuery plugins
  • /script.js - site/page specific JavaScript

The Build Folder Structure

The build/ folder contains the following elements:

build.xml

Apache Ant's build files are written in XML. This file contains our project (Boilerplate Build) and targets. Targets contain task elements. Each task element of the buildfile can have an id attribute and can later be referred to by the value supplied to it, which must be unique.

default.properties

default.properties contains the default build options, project structure and hardcore build options, which we'll review shortly.

build.properties

This file defines overrides for default.properties. This should be created by a user when he or she needs to override particular values. Consequently, it should not be placed under version control.

tools

Tools are a set of bundles, which include opyipng, JPEGTran, YUI compressor and HTML compressor.


Set up the Build Tool

Because the goal of the build tool is to be platform agnostic, we'll review the necessary steps to set it up, dependent upon your OS of choice.

  • Windows - Grab and install WinAnt.
  • Mac OSX - Using homebrew, install the following packages: brew install libjpeg optipng. With MacPorts, use the following install command: port install jpeg optipng
  • Ubuntu (Linux) - Using apt, install the following packages: apt-get install libjpeg-progs optipng

Walkthrough of the buildfile

The build tool is nothing more than an XML file that is based on Apache Ant. Below is a walk through of the pre-defined build process. These elements can be configured by editing the build.xml file.

Concatening / Minifying JavaScript

<!-- Optimize javascript files -->
<target name="js.all" depends="js.remove.console, js.all.min, js.main.concat, js.libs.concat, js.concat.scripts, 
js.minifyonly.min, js.delete"></target>
<!--  JS: Concat primary scripts -->

...

<!-- JS, Delete concatenated libs file (only if concat.scripts and delete.unoptimized are defined) -->
<target name="js.if.concat.scripts" if="build.delete.unoptimized, build.concat.scripts">
	<delete file="./${dir.publish}/${dir.js}/libs-${build.number}.min.js"/>
	<delete file="./${dir.publish}/${dir.js}/scripts-${build.number}.min.js"/>
</target>
  • The /js/libs/ files are minified, but not concatenated. Modernizr should be alone in the head of the document. jQuery might be pulled from a CDN, and the pngfix will be included for IE6 only.
  • /js/mylibs/ contains your other various JavaScript libraries and plugins. All files stored here here will be minified (unless they end with .min.js), and then concatenated together.
  • plugins.js and script.js, in the /js/ folder, are all yours. These will also be minified and concatenated with the mylibs/ files.

Minifying CSS

<target name="css" depends="copy">
    <echo message="Minifying css..."/>
    <concat destfile="./${dir.publish}/${dir.css}/style-${build.number}.css">
     <fileset file="./${dir.css}/style.css"/>
    </concat>
    ...
</target>

All CSS files are minified using YUI compressor. The above Ant script will run style.css through YUI compressor for minification.

Image Optimization

<target name="imagespng" depends="copy">
	<echo message="Optimizing images"/>
    <apply executable="optipng" osfamily="unix">
     <arg value="-o7"/>
     <fileset dir="./${dir.publish}/">
       <include name="**/*.png"/>
     </fileset>
    </apply>
    ...
</target>

In HTML5 Boilerplate, we chose to use OptiPng and jpegtran for image optimization for PNG and JPG images, respectively. That said, there are plenty of image optimization tools. Should you wish to do so, you're free to replace the tools with your own favorite image optimization tools.

For instance, Smush.it uses ImageMagick to identify the image type and convert GIF files to PNG files. It then uses gifsicle to optimize GIF animations by stripping repeating pixels in different frames.

Removing Development-Only Coding

<exclude name="**/${dir.js}/profiling/**"/>
<exclude name="**/${dir.test}/**"/>
...
<target name="js.remove.console" description="Comment out console.log lines">
	<echo>Commenting out console.log lines</echo>

	<replaceregexp match="(console.log\(.*\))" replace="/\*\1\*/" flags="g" >
		<fileset dir="./${dir.publish}/${dir.js}/">
			<include name="**/*.js"/>
			<exclude name="**/*.min.js"/>
		</fileset>
	</replaceregexp>  
		
</target>

Files like console.log, profiling and unit testing files are not needed for the release of the site.

Minifying HTML

<target name="htmlbuildkit" depends="html" >

<apply executable="java" parallel="false" force="true" dest="./${dir.publish}/" >
     <fileset dir="./${dir.publish}/" includes="*.html"/>
     <arg value="-jar"/>
     <arg path="./${dir.build}/tools/htmlcompressor-0.9.3.jar"/>

</apply>
</target>

Listed below are some various options for minifying your HTML files:

  • htmlbuildkit - Preserves comments, multiple spaces and compresses inline JavaScript and CSS.

  • htmlclean - Preserves multiple spaces, removes unneeded quotes and compress inline JavaScript and CSS

  • htmlcompress - Removes unneeded quotes and compresses inline JavaScript and CSS.

Automated Baseline Numbering / Cache Busting

HTML5 Boilerplate uses query string for JavaScript/CSS versioning and cache busting.

HTML5 Boilerplate by default uses query string for JavaScript/CSS versioning and cache busting. The drawback with this approach is that some intermediate proxies - and potentially other clients - may not cache assets that contain query strings. This is due to basic heuristics that flag such requests as dynamic data.

The build tool will first remove the query string versioning and use automated baseline numbering for release control and cache busting.

Configuring Excludes

<exclude name=".gitignore"/>
<exclude name=".project"/>
<exclude name=".settings"/>
<exclude name="README.markdown"/>
<exclude name="**/.git/**"/>
<exclude name="**/.svn/**"/>
<exclude name=".gitignore"/>
<exclude name="*.conf*"/>
<exclude name="mime.types"/>
<exclude name="**/${dir.build}/**"/>
<exclude name="**/${dir.test}/**"/>
<exclude name="**/${dir.demo}/**"/>
<exclude name="**/${dir.js}/profiling/**"/>

Not all files will need to be published. A perfect example of this would be files generated by versioning control system like subversion and git.

By default, there is a list of file types and directories that will be excluded. To add to this list, you can search and find <!-- configurable excludes --> and append your custom exludes to it.


Walkthrough of default.properties

Variables inside the build file are defined in default.properties and build.properties.

Build options

  • build.concat.scripts = true - If set, multiple script files will be smushed together to a single, cohesive file.
  • build.delete.unoptimized = true - If set, unoptimized files will be deleted.
  • file.exclude = nonexistentfile - Excludes file filter for publishing (can't be empty).

Project Structure

dir.publish	= publish
dir.build	= build
dir.tools	= ${dir.build}/tools
dir.test	= test
dir.demo	= demo
dir.js		= js
...

The project structure contains directory names, like the ones shown above, as well as the core JS folder, JS utility libraries, and folders which should only be minified but not concatenated.

Other Build Options

  • build.info = buildinfo.properties - Build versioning is defined
  • tool.yuicompressor = yuicompressor-2.4.2.jar - YUI Compressor is defined with yuicompressor-2.4.2.jar

Okay - But How Do I Use This?

Finally, we'll learn exactly how you can use the build tool in your projects! Refer to the following steps to run the build tool.

  • Open a command line interface, and navigate to your project folder.
  • Navigate into the build folder: cd build/
  • There are four different ways to build your site: the default way is: ant build
  • When the build script changes your HTML to reference the new minified script (usually named something like scripts-002.min.js), it looks for some HTML comments which refer to the beginning and end of the script block. Currently, it looks for <!-- scripts concatenated and <!-- end concatenated and minified scripts-->.

Build Options

Here's a list of various build options that you can choose from to suit your particular need:

  • ant build - minor html optimizations (extra quotes removed). inline script/style minified (default)
  • ant buildkit - all html whitespace retained. inline script/style minified
  • ant minify - above optimizations plus full html minification
  • ant text - same as build but without image (png/jpg) optimizing

Conclusion

Performance optimization doesn’t have to be expensive or time consuming. With some reusable rules, one can slowly setup a build process to automate the repetitive aspects of optimization work. Apache Ant provides a powerful, yet easy to use, framework, while HTML5 Boilerplate leverages that to make web optimization as easy as possible for front-end web developers. Thank you so much for reading!