Clientside Moment Profiling


When developing complex JavaScript applications, it is useful to profile the loading of your pages, so you can better understand the bottlenecks of performance. To the end user, the most important moment is when the browser indicates that the page is finished loading. As developers, it is our job to understand why loading takes so long and how to improve it. Today's article will introduce a simple widget called MomentTracker, which allows you to easily compile a collection of important client-side moments and then output them.

How to do it…

Include the following snippet as the first element in your head element:

var __momentTracker = {
	aMoments: [],

	addCookieHandler: function() {
		YAHOO.util.Event.on(window, 'unload', function() {
			var oneMinuteLater = new Date();
			oneMinuteLater.setTime((new Date()).getTime() + 60000);
			YAHOO.util.Cookie.set('__momentTracker', new Date(), {expires: oneMinuteLater});
		});
	},

	rollup: function() {
		var lastPageTime = YAHOO.util.Cookie.get('__momentTracker'),
			aMoments = __momentTracker.aMoments,
			rs = [],
			i, t1, t2;

		if (lastPageTime) {
			__momentTracker.lastPage = new Date(lastPageTime);
			aMoments.unshift('lastPage');
		}

		for (i=aMoments.length-1; 0

Then anytime you want to track an important moment, call the trackMoment function with the name you would like to call that moment:

To measure the time between pages, we need to setup a cookie (call this anytime after YAHOO.util.Cookie and YAHOO.util.Event are included):

__momentTracker.addCookieHandler();

And lastly, to output the results call:

Event.on(window, 'load', function() {
	__momentTracker.trackMoment('afterJavaScript');
	Y.log(__momentTracker.rollup().join("\n"));
});

How it works…

The trackMoment function simply stores a date object, at the moment it is executed. The addCookieHandler function adds an unload event to record when the user leaves the page. The rollup function iterates on all the moments, calculates the difference between them in milliseconds, and then returns the results.

The implementation in this article, uses the YUI Logger module to print the results. However, you could modify the rollup function to suit your needs, and use the results in a more meaningful way. At Mint.com we pass the tracked moments times to the server, where they are aggregated into our performance monitoring system.

I've put together a quick demo page to show it working.

Using Data URIs


After reading Nicolas Zakas article, Data URIs make CSS sprites obsolete, I was inspired to see how easy it would be to put into practice. His CSSEmbed JAR uses Base64 encoding for data URIs and MHTML to be backwards compatible with IE 6 and 7. So the logical step was to create a build script that runs CSSEmbed against all my CSS files.

continue reading article…

Simple JavaScript Function To Include CSS


This article explains how to write a simple JavaScript function to include CSS files and notify when the loading of the file is complete. The issue is that most browsers do not fire a load event when the link element finishes processing the included CSS rules. And while many libraries have mechanisms for notifying when the CSS is included, I believe this technique is lighter and more elegant. A special thanks goes out to the UX team at Facebook.com who first described this technique to me.

continue reading article…

Function Hijacking Pattern


Sometimes when working with JavaScript libraries and widgets, you may want to extend or augment the behavior of certain functions without breaking the existing functionality or completely extending the object. Today's article will explore the Function Hijacking Pattern, which can be used to augment a function with your own logic.

continue reading article…

Defer Function Execution Until Variables Are Available


I recently wrote this simple function, which hijacks a function attached to an object, automatically deferring calls to it (in the order received), until an availability function returns true. I find this to be useful in large applications with many dependencies, especially third-party ones, where it can be difficult to know that the variables/functions used by a function exist. And rather than check for the variables and handle function deferment manually, the function in today's article will manage deferment automatically for you.

continue reading article…