Over a million developers have joined DZone.

RequireJS and Google Analytics' Innovative Async Script Loaders

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

As the code complexity of websites grow and assembly gets harder, these sites that more closely resemble web apps require more discrete JavaScript files and modules for development with optimized code in a small number of HTTP calls.  Node.js is a great JS framework for asynchronously running apps, but it starts with synchronous require() calls, which is a problem for require()-esque loader code.  Two projects that help out in these situations: RequireJS and an innovative asynchronous loader for Google Analytics.

RequireJS
RequireJS implements the CommonJS Transport/C proposal API.  This is a loader for plain JS files and more defined modules.  It works best in the browser, but it can also be used in other JavaScript environments like Rhino.  It allows easy debugging because it uses plain script tags for loading.  When the file defines a JS module via require.def(), RequireJS facilitates better CommonJS support and can load multiple versions of a module in a page.  RequireJS also supports module modifiers and has a plugin system for things like i18n string bundles and text file dependencies.

Require JS offers a solution for the require()-esque loader code with the ability to load nested dependencies, ease the use of front-end development with an optimization tool that helps deployment, and a form of #include/import/require.  Dojo, LABjs, and CommonJS script loading APIs don't solve all of the problems that RequireJS solves.  Here is the result of what RequireJS does:
// code that runs asynchronously when the library is loaded
require(["some/script.js"], function() {
//This function is called after some/script.js has loaded.
});

// defining the module and dependencies
require.def(
// The name of this module
"types/Manager",

// The array of dependencies
["types/Employee"],

// The function to execute when all dependencies have loaded. The arguments
// to this function are the array of dependencies mentioned above.
function (Employee) {
function Manager () {
this.reports = [];
}

// This will now work
Manager.prototype = new Employee();

// return the Manager constructor function so it can be used by other modules.
return Manager;
}
);

Google Analytics Asynchronous Tracking
Blocking was a longstanding problem for Google Analytics, but a new asynchronous loader is changing all that.  The Asynchronous API allows you to start pushing commands immediately because you can create an array that uses the push() method to put commands on a queue.  Once the Google Analytics code is done with its asynchronous loading, it takes over the array by wrapping the standard methods.  After that, the Asynchronous API can take the commands and send them back to Google Analytics and push() can perform more tasks.

This snipped is the minimum configuration needed to track a page asynchronously in Google Analytics:
<script type="text/javascript">

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
})();

</script>

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}