While we love The Dojo Toolkit, we're not sure if it's even possible for one application to use all of its functionality. At Swivel, we use many of dojo's charting components, but not much else. One of our chart pages will pull in several dozen Javascript files as dojo imports the resources it needs at runtime. Surely there has a way of getting all the dojo we need, and nothing else? Well, the Dojo Foundation hivemind has thought of that.
63% Extra, Free!
Let's put our results above the fold: packaging our dojo files cut the load time for our most dojo-intensive pages by 63% on average and dramatically reduced the number of individual requests. The change for one page was as follows:
There's good documentation for using Dojo's system for packaging custom builds. You'll need the src build which includes the util directory -- for our purposes we needed to tweak our .braids file to include:
public/javascripts/dojotoolkit/util:
squashed: true
url: http://svn.dojotoolkit.org/src/util/trunk
type: svn
revision: 18839
remote: braid/public/javascripts/dojotoolkit/util
(I'll save all the gory details of installing git+svn to get braid to work locally for another, longer, and more painful post. Word to the wise: you may need the apr Portfile.)
Selecting the dojo components you need is straightforward enough. Have a look at what dojo files your page is requesting and work from there. Our build profile ended up looking like this:
dependencies = {
layers: [{
name: "swivel_dojo.js",
dependencies: [
"dojox.charting.Chart2D",
"dojox.charting.themes",
'dojox.gfx.svg',
'dojox.nls'
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ]
]
};
What we wanted to do, though, was to have the raw dojo files under source control through Braid, and only use the package in production. Debugging the single humongous line of generated Javascript is tricky, for one thing, and managing the versioning of the Dojo toolkit files properly was also important. This required a bit of trickery.
Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo
We created a dojo_release directory as a sibling of dojotoolkit, and added a symbolic link called dojo that points back up to dojotoolkit. So public/javascripts/dojo_release/dojo is a symbolic link to public/javascripts/dojotoolkit. That's the version that gets checked in to source control, and all files that use our dojo build have this line of Javascript:
<%= javascript_include_tag('dojo_release/dojo/dojo/dojo', 'dojo_release/dojo/dojo/swivel_dojo', '...' %>
Now everything should work as before, we're just getting to the dojo files in a different way. So anyone checking out the source and working with it will see no difference except the paths for those Javascript files. Or, to put it another way, we haven't really done anything yet.
What we want the dojo packaging script to do is run against our new profile and output the packaged version into the dojo_release directory, clobbering the symlink with the compiled package. The best time for this to happen would be after the code is updated via our deploy:update_code task. And, so, a new task is added to configuration/deploy.rb:
namespace :dojo do
desc "package dojo files using Swivel profile"
task :package, :roles => :db, :only => { :primary => true } do
run <<-SCRIPT
rm #{release_path}/public/javascripts/dojo_release/dojo &&
cd #{release_path}/public/javascripts/dojotoolkit/util/buildscripts &&
./build.sh profile=swivel action=release releaseDir=../../../dojo_release
SCRIPT
end
end
and
after "deploy:update_code", "deploy:dojo:package"
The SCRIPT heredoc consists of multiple lines chained with && because Capistrano will otherwise instantiate a new session for each command. It's important to go to the buildscripts directory unless you've done some munging of your Java classpaths or whatever it is Java needs, I don't know and I'm not sure I want to know. And, finally, setting the build script's releaseDir will put the packaged dojo javascript where your existing javascript_include_tag can find it.
And that's it. Run cap deploy and the script should run, packaging all the dojo code it needs into a single (huge!) line of Javascript. When you view your deployed app using a debugger like Firebug or Webkit's built-in developer tools, you'll see how the Javascript files are being served differently. And your users won't need those tools to see the difference.
Recent Comments