Home
Welcome to DUI! If you’re reading this, you’ve likely already been sold on the performance and elegance that DUI adds to sites built with jQuery. If not, stay a while and listen. You may be pleasantly surprised by how easy it is to manage even enterprise JavaScript with DUI.
Core Concepts
DUI is a framework for organizing your JavaScript and making it load really, really fast. To meet those two basic needs, we do the following:
Speed:
- Include an ultra-light, inline boot-strapper (~2KB page weight gzipped, zero http requests)
- Listen via event delegation for feature requests
- Detect and load required files with a minimum of fuss and no redundancy
- Transparently execute the feature you asked for on the same event
- Bind all other controls for that feature so you don’t have to load it again
Organization:
- Wrapping any script in a DUI() call will reconcile dependencies and prevent any race conditions
- You can nest a DUI call and they’ll resolve first-in-first-out, easy peasy
- Say goodbye to dependency hell and clunky syntax: No manual timing, no worries about script order
- DUI.Class provides prototypal object-oriented JS, without tacking other languages’ patterns on
With those two goals in mind, we wrote a JS boot loader that allows a page to render with no initial HTTP requests for JS at all — let alone blocking ones — and has no delay between rendering and interactivity. There is no point at which an element that needs behavior is rendered without an event listener to load and execute that behavior. Those two key features are, in our humble opinion, pretty seriously badass.
Hello World
- Put DUI.min.js inline in your head tag
- Set DUI.scriptURL to the URL from which you load JS
- Copy any DUI tools you need to a folder at DUI.scriptURL + ‘/DUI’
- Specify where/how you want a feature to load:
<a class="someControl _click:controls">I want to believe</a>
- Write your feature:
//In DUI.scriptURL + 'controls.js' $('.someControl').live('click', function() { console.log('Hello world!'); });
There you go, you’re done. You now have a deferred feature that will log “Hello world!” to the console when you click that link. The feature adds no HTTP requests to your initial page load and is fully cacheable for return visitors.
Feature Requests
Features are loaded by DUI when a user needs them. To accommodate the most common cases, we currently support click, hover and page load. So how do we detect these requests? We do it by looking for a specific class name on the element that generated the click or hover, or any element that exists on the page when it loads in the case of the ‘page load’ handler.
The basic structure of the special class name is: _event:OptionalDirectoryName:fileName e.g.:
//Loads DUI.scriptURL + 'doStuff.js'
<a class="_click:doStuff"> ... </a>
//Loads DUI.scriptURL + 'MyApp/myFeature.js'
<div class="_hover:MyApp:myFeature"> ... </div>
//Loads DUI.scriptURL + 'MyApp/SubDir/someFile.js'
<input type="button" class="_load:MyApp:SubDir:someFile" />
After a feature is loaded, all class names that match it are removed from the DOM.
Maps (…wait, they don’t load you like I load you)
Got a particularly ungainly path to load a feature from? Or maybe you want to use a CDN in production but not in development. No worries, use a map:
//In your <head> tag:
<script type="text/javascript">
//*DUI.min.js goes inline here*
DUI.maps._cdn1 = 'http://media.mycdn.com/';
</script>
Now you can load a feature like so:
//Loads 'http://media.mycdn.com/' + 'doStuff.js'
<a class="_click:_cdn1:doStuff"> ... </a>
Also, a map can be any string, including DUI modules. It can be highly useful when you want to force a feature request to point somewhere else. For instance, if you’d like to force DUI to load DUI.Class from a CDN:
//In your <head> tag:
<script type="text/javascript">
//*DUI.min.js goes inline here*
//DUI.Class will now be auto-loaded from this url instead of DUI.scriptURL + 'DUI/DUI.Class.js'
DUI.maps['DUI.Class'] = 'http://media.mycdn.com/SomeOtherPath/Alternate.DUI.Class.js';
</script>
Dependencies and Timing
The DUI() function is easy to use and has a few handy behaviors built-in:
DUI(['lib/SomeClass'], function() {
//Note that you never have to manually specify DUI features as dependencies.
//Any use of DUI internals or addons will be detected and handled.
var foo = new DUI.Class();
});
The preceding code will trigger the following actions when run:
- Make sure jQuery exists. If not, load it
- Load DUI.scriptURL + ‘DUI/DUI.Class.js’
- Load DUI.scriptURL + ‘lib/SomeClass.js’
- When those three files are done, fire the anonymous function that was passed in
For this example’s sake, let’s say that SomeClass.js also has a DUI() call in it that has no additional dependencies:
DUI(function() {
SomeClass = new DUI.Class();
});
So what happens now? Two DUI() calls have fired and three scripts are on their way in and this one uses DUI.Class too and… well… it all just works.
We already know that DUI.Class is loading, so we’re covered there. We also know the status of SomeClass and jQuery (SomeClass has loaded and is waiting on dependencies, jQuery is probably almost done by now if it wasn’t already cached) so we take the safe and sane route: Wait until every script needed is ready, then fire the callbacks in the order they were found.
In general, you don’t need to think about timing at all if you wrap a script in a DUI callback. You do still need to let it know if you need an external file loaded, but hey, we can’t do all the work for you ;)
Known Issues
This is an alpha, there are bugs. They’ll be fixed soon I promise.
- File-extensions other than .js can cause the loader to freak out
- The _view trigger is VERY alpha right now and only handles scrolling reliably in Firefox
- Feature request events don’t bubble yet, so _click and _hover should be added to the original event target
- Failed script loads don’t throw errors yet, so you’ll have to check for bad file paths manually for now
- Do you use a browser other than Firefox for development? If so, you will likely be plagued by locusts when trying to make this script work
