You’ve likely read that the new dgrid can be as small as 32KB gzipped when including just its minimal dependencies. However, if you use the standard settings for the Dojo Web Builder or a standard Dojo build profile, you end up with a build that’s closer to 100KB gzipped. So, how do you actually get dgrid and Dojo to be a small as possible? Use a custom build.

Where to start with Dojo Builds

The Dojo build tutorial is an excellent starting point for learning about builds, but it’s definitely not the simplest and most straightforward thing to learn when first using Dojo. And while the Dojo Build reference guide is thorough, it can be a difficult starting point when you just want an example build. The Dojo Boilerplate is also a nice starting point for building an app, but it’s much more than you need when just trying to get a dgrid example up and running.

Example Build Profile

So, instead, here’s a build profile you can start with and modify, with an explanation of each section of the build profile. For this example, I’m using a pre-release version of Dojo 1.8, Node 0.6.18, and dgrid beta 0.3.1. This should also work with Dojo 1.7.2 or the upcoming 1.7.3.

We start by placing our profiles in our base path to simplify URL issues. You should always define a releaseDir, because we’ve seen cases where you can accidentally overwrite your source tree without it.

var profile = {
	basePath: './',

	releaseDir: "./release/dgrid",

Next, we define our packages. Because each of the packages we’re including is “AMD-ready” and has a Dojo build file provided defining the package instructions for the Dojo build system, we can keep this simple:

	packages: [
		'dojo', 'dijit', 'dgrid', 'xstyle', 'put-selector'
	],

If a package did not have a package.json and a build file, you would need to use resource tags to explicitly state that a package is AMD, and to then exclude tests, define which files to only copy and not build/compile, etc.

We then specify a number of configuration flags. We remove CSS comments, we keep tests in our build, we use the Closure Compiler to optimize our code, we strip all console statements, and we use the lite selector engine since we don’t need the full overhead of Acme or Sizzle or Slick for dgrid in modern browsers.

	cssOptimize: 'comments',
	// include the tests for now
	mini: false,
	optimize: 'closure',
	layerOptimize: 'closure',
	stripConsole: 'all',
	selectorEngine: 'lite',

Our build layers are the two JS files that are going to be created:

  • Our dojo/dojo layer will write a file at dojo/dojo.js which simply contains dojo/dojo, which is Dojo’s AMD loader, and other very core features.
    • dojo/domReady is the AMD plugin for determining that the DOM is indeed ready, and dojo/_base/declare gives us support for basic class declarations.
    • boot: true means that this layer can be loaded with a script tag and knows how to kick off the AMD loader.
    • customBase: true means we do not wish to use the larger default Dojo Base, which weighs in at about 35KB gzipped.
  • For the dgrid layer, we’ll write the layer file to dgrid/dgrid.js. We’re including the dependencies necessary to run a performance test that’s included as part of the standard dgrid package.
	layers: {
		'dojo/dojo': {
			include: ['dojo/dojo', 'dojo/domReady', 'dojo/_base/declare'],
			boot: true,
			customBase: true
		},
		'dgrid/dgrid': {
			include: ["dgrid/List", "dgrid/OnDemandGrid", "dgrid/Selection", 
				"dgrid/Keyboard", "dgrid/test/data/perf"]
		}
	},

We then finish our profile file with some overrides for feature detection tests. Basically we want these tests to fail at build time, which will prevent the inclusion of these features within our build when we minify using the Closure compiler. You can also set features to true in the case that you want to unconditionally include a browser or platform-specific feature into your build.

staticHasFeatures: {
		// The trace & log APIs are used for debugging the loader,
		// so we don’t need them in the build
		'dojo-trace-api': 0,
		'dojo-log-api': 0,
		// This causes normally private loader data to be exposed for debugging,
		// so we don’t need that either
		'dojo-publish-privates': 0,
		// We’re fully async, so get rid of the legacy loader
		'dojo-sync-loader': 0,
		// We aren’t loading tests in production
		'dojo-test-sniff': 0
	}
};

The build output will now include two optimized JS files, contained within full source trees for Dojo and dgrid, as well as xstyle and put-selector, which are dgrid’s dependencies. The full source tree is there in case you need to include other modules that are part of those packages later.

In order to obtain dgrid, just follow the instructions for downloading it, or ideally use CPM to install it. One issue I ran into on Mac OS X Lion was that I had to explicitly define the CPM_PATH when running the command or in my shell source.

Using the Build

First, download the build profile and modify any path or other configuration settings as you see fit. As mentioned, we’ll typically place the build profile in the parent directory of dojo and dgrid. From the command line, with Node installed, we run the following command:

util/buildscripts/build.sh -p sitepen.profile.js -r

After about a minute, we’ll have our built files saved in the release directory. Note that this copies the entire source tree also, in case you later want to include other modules on-demand with Dojo, Dijit, or dgrid.

We’re not quite done yet. In our original markup for this simple test ( dgrid/test/performance.html ) , we have the following script include and require statement:

<script type="text/javascript" src="../../dojo/dojo.js"
	data-dojo-config="async: true"></script>
<script type="text/javascript">
	require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", 
		"dojo/_base/declare", "dgrid/test/data/perf", "dojo/domReady!"],
		function(List, Grid, Selection, Keyboard, declare, testPerfStore){
		...

However, if we use our build layer for dgrid with this, it will still load separate modules for List, OnDemandGrid, etc. So, we use a nested require:

<script type="text/javascript" src="../../dojo/dojo.js"
	data-dojo-config="async: true"></script>
<script type="text/javascript">
	require(['dgrid/dgrid'], function () {
	    require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", 
		"dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/perf", 
		"dojo/domReady!"],
		function(List, Grid, Selection, Keyboard, declare, testPerfStore){
		...

This first loads the layer, and then once that is loaded, because each of the needed modules is already available through the Dojo loader, the separate modules are not re-requested.

Results

Let’s compare the before and after waterfall loading diagrams:

As you can see, this provides a dramatic improvement in load times (reduce the load by 75% on a fast network, likely greater on a slower network), the number of HTTP requests (from 42 to 6), and the total payload size (from 123KB to 31.6 KB, both gzipped).

Making Your dgrid Fast

To make your dgrid fast, you’ll want to update your layers in the build profile to optimize for the features you want to include in your grid and app.

We’re working hard with our customers to replace their massive grid implementations with dgrid and we can do the same for your application! Call us today to get on the schedule to receive a full grid migration effort or sign up for one of our valuable SitePen Support plans to keep your developers productive and informed!