Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Friday, April 27, 2007

JavaScript Memory Leaks

On one of my projects, http://www.mint.com, I recently noticed severe performance degradation in IE6 the longer I kept the browser open. As it turns out a lot of the techniques used by JavaScript Frameworks, and even my own JavaScript architecture, causes memory leaks. This is especially prominent in IE6, because its memory manager has poor heuristics for detecting JavaScript leaks. It’s not as important in better browsers like, Firefox, but I do notice that Firefox slowly eats up memory as well (although this may be a documented browser memory leak). It was particularly noticeable on Mint because our JavaScript library has become bloated to well over 15,000 lines of code and IE6 just can’t handle so much leakage.

CORRECTION - Firefox memory leak, is actual a feature and not a bug. If you want to prevent Firefox from using too much memory, read this article:
http://forevergeek.com/open_source/debunking_another_myth_firefoxs_memory_leak_bug.php

Some things to improve performance are: avoid using closures, don’t do circular references, and when appending DOM elements always build from the document deep. That’s all I’m going to say, because this is a very complicated issue and I don’t have the time to do the proper analysis. However, these three articles cover everything you really need to know:

IE Leak Patterns
Closures and Circular References
Leak Patterns

posted by Matt Snider at 12:23 am  

Wednesday, April 25, 2007

Object Oriented Programming (OOP) in JavaScript

First, in case you’ve been living under a rock the last 20 years (OOP).

JavaScript uses the Prototype Pattern design and therefor lacks the concept of a Class. Instead everything relies on the Object type and prototyping functions attached to Objects.

The following example takes the native Date object and adds a static array to it, then prototypes the function getMonthName that will return the month name String for the date:

Date.monthNameList = ['January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December'];
Date.prototype.getMonthName: function() {
	var i = this.getMonth();
	return Date.monthNameList[i];
}

The first line, attaches the array of Month strings to the native Date Object. This Array behaves like a ’static’ variable from other common OOP languages, like Java & C++. The getMonthName function is added to the prototype Object on the Date Object, so every instantiation of the Date Object will be able to use getMonthName. For example:

var date = new Date();
date.setMonth(0);
var month = date.getMonthName();

Here we create a Date Object, date, and set its month to 0, which is January in JavaScript (0=Jan, …, 11=Dec). Then, we call the new method getMonthName on the ‘date’ object (an instantiation of Date), which will return ‘January’. You can prototype all of the Native Objects, but should never prototype Array or Object, as doing so will make traversing them needlessly painful. The native String Object is never instantiated with the ‘new’ operator, but nonetheless, all strings will have any methods you prototype on the String object. As will Arrays, Objects, and Regex when created with their respective short-hand notations ([], {}, /…/).

Now prototyping native Objects is useful, but it is far more powerful to prototype your own functions. Here is an example using ArrayUtil (on which I prototype all my array traversing/parsing utility methods, instead of prototyping the Array Object):

var ArrayUtil = {};
// removes empty elements from arrays
ArrayUtil.prototype.compact(arr) {
	var newarr = [];
	for (var key in arr) {
		var value = arr[key];
		if (value) {
			newarr[key] = value;
		}
	}
	return newarr;
}
var arrayUtilMgr = new ArrayUtil();
var anarray = ['a', 'b', 'c'];
anarray[1] = null;
newarray = arrayUtilMgr.compact(anarray);

In the first code block, we create the ArrayUtil Object and prototype the function ‘compact’ that removes empty values from an Array. Then, we instantiate the ArrayUtil Object to a global (window) scoped variable, arrayUtilMgr, which will be our global reference to the ‘compact’ function. In the second code block, we create an Array with values 0=’a', 1=’b', 2=’c’ and set the value at index 1 to null. Then running the compact function on ‘anarray’, sets newarray to an Array with values 0=’a', 2=’c’. Note that this particular example preserves the keys of the first array, which is what I wanted (in this case), but it could have easily not preserved keys, returning an Array with values 0=’a', 1=’c’. The ArrayUtil Object will be discussed in more detail in a future article.

Now, the last element of Object prototyping is the ‘this’ keyword, which refers to the owning Object’s scope. Generally, the scope of Objects will be the window, but when referencing methods on an instantiated Object, ‘this’ refers to the Object itself. Therefore, all prototype defined methods can reference the instantiated Object with the ‘this’ keyword. In the Date example (above), notice I used the ‘this’ keyword to reference the Date Object and retrieve its month. The Prototype based Frameworks and Toolkits profusely use the ‘this’ keyword and we will be discussing how in a future article. Lastly, it is important to mention that maintaining scope in JavaScript can be a real nightmare and is not for the weak of heart.

Recommended Reading:
preserving-scope-in-javascript

posted by Matt Snider at 7:39 pm  

Monday, April 16, 2007

Frameworks, Toolkits, Etc.

To start this discuss, we must first decide what is a framework vs. a toolkit vs. any other name we might use. These words are often used interchangeably when discussing JavaScript libraries and can be confusing.

Framework: A fundamental structure, as for a written work.

Toolkit: A set of software applications that aid a task.

So for the sake of this blog, we will refer to any library that provides fundamental underlying architecture that will be used across the entire site as a ‘Framework’ and a small set of tools as a ‘Toolkit’, and any collection of code can/will also be referred to as a ‘Library’. Using these guidelines, ‘moo.fx’ would be considered a toolkit, as it is a compact set of tools that may be used to extend the prototype framework, and ‘Google Web Toolkit (GWT)’ will be called a ‘Framework’, as it is a complete architecture (even though it is misnamed). And both would be considered a ‘Library’.

With that out of the way, let’s dive into the meat of todays article, popular JavaScript frameworks and toolkits. There are enough JavaScript libraries to fill volumes of books, so we won’t be able to discuss all of them. This blog will consider the following list: prototype, script.aculo.us, rico, dojo, mochikit, gwt, yui, jquery, and moofx. If you know of another library that is widely used, please leave a comment and I will consider adding it to the discussion.

Today, we begin our library discussion by: looking at what libraries there are, where you can find them, and a little history about each. This will be a growing document and will always be available at the link below:

http://mattsnider.com/?page_id=9

Additionally, I here are some other articles I have written about Frameworks:

More on Frameworks

posted by Matt Snider at 2:27 pm  

Sunday, April 8, 2007

True, Truthy, WTF

As you probably know, JavaScript has keywords for true and false. These keywords are of the quasi-type ‘boolean’ and can be detected with my isBoolean() function that uses the ‘typeof’ keyword. What you may not know is that JavaScript, like many C-style derived languages, has the concepts of truthy and falsy. This concept is important because most of the JavaScript Frameworks, which we will soon be analyzing, make use of this feature.

These are non-boolean expressions that can be treated as a boolean value. The number zero is falsy, and any other number is truthy. Equally for strings, an empty string is falsy, and a non-empty string is truthy.

from TruthyFalsyAndTypeCasting

For an in-depth look at the concept ‘truthy’ vs the ‘keyword’ true, I created this test page: False Vs. Falsy Test Page

The best practice approach, is to use the keywords true and false, and try to avoid code that uses 0 and 1 for the purposes of truthy and falsy. It is acceptable to use truthi-/falsiness to determine if a variable does not have a value:
var obj;
if (obj) {
// do something
}
else {
// error management code
}

posted by Matt Snider at 5:49 pm  

Wednesday, April 4, 2007

Type Detection

Common JavaScript Interview question: What are the object types in JavaScript?

The short answer is that there is only one type in JavaScript: Object. However, this is not really the whole truth, as JavaScript has 7 meta-types: Number, String, Boolean, Function, Object, Null, Undefined.

Since JavaScript is not a strongly typed language and in fact every object descends from the ‘Object’ type, you may find it helpful to manage types yourself. I personally, always manage types as it allows me to bulletproof my JavaScript functions and prevent other developers from breaking my code. Also, AJAX applications often return bad data because lot can go wrong with the request and server-side code execution. I have developed a simple set of functions that I always include in my ‘core.js’

Below is a list of functions that I use to detect object types:

isAlien:
/* True, if the object is not part of a function. */

function isAlien(o) {return isObject(o) && !isFunction(o.constructor);}

isArray:
/* True, if the object is constructed of the native Array Object */

function isArray(o) {return isObject(o) && o.constructor == Array;}

isBoolean:
/* True, if the object is of the meta-type ‘boolean’ */

function isBoolean(o) {return ‘boolean’ == typeof o;}

isDate:
/* True, if the object is an Object with the getMonth method */

function isDate(o) {return isObject(o) && o.getMonth;}

isDomElement:
/* True, if the object is set and has children nodes or a node type */

function isDomElement(o) {return o && (”undefined” !== typeof o.childNodes || o.nodeType);}

isEvent:
/* True, if the object is set, the native Event Object is defined, and the object has an event phase */

function isEvent(o){return o && “undefined” != typeof Event && o.eventPhase;}

isNull:
/* True, if the object is null */

function isNull(o) {return null === o;}

isFunction:
/* True, if the object is of the meta-type 'function' */

function isFunction(o) {return ‘function’ == typeof o;}

isNumber:
/* True, if the object is of the meta-type ‘number’ and is finite as determined by the native function */

function isNumber(o) {return “number” == typeof o && isFinite(o);}

isObject:
/* True, if the object is of the meta-type ‘object’ or ‘function’ */

function isObject(o) {return (o && “object” == typeof o) || isFunction(o);}

isSet:
/* True, if the object has any value, including 0 and false, both of which are normally falsy */

function isSet(o) {return ((o || false === o || 0 === o) && ! isNull(o) && ” !== o && ! isUndefined(o));}

isString:
/* True, if the object is of the meta-type 'string' */

function isString(o) {return ’string’ == typeof o;}

isUndefined:

/* True, if the object is of the meta-type 'undefined' */

function isUndefined(o) {return ‘undefined’ == typeof o;}

isEmpty:

/* True, if the object does not have any members that are not functions */

function isEmpty(o) {
var i, v;
if (isObject(o)) {
for (i in o) {
v = o[i];
var t = isUndefined(v);
var t1 = isFunction(v);
if (! isUndefined(v) && ! isFunction(v)) {
return false;
}
}
}
return true;
}

*note: most of these functions are not bulletproof and can be fooled. For example:
var fakeDate = {
getMonth: 1234
};
isDate(fakeDate) /* this will be true */

I have not found a good way to prevent this type of abuse, except through intelligent coding. You should never use reserved names or those names used by other native JavaScript Objects, like Date and Array, when writing application objects.

posted by Matt Snider at 4:05 pm  

Sunday, April 1, 2007

Getting Started - Development Tools

Before a craftsman can truly ply his trade, he must be equipped with the proper tools; Web Application Developers (WAD) are no exception. Below is a list of the tools that I have found to be most useful.

Firefox by Mozilla, Inc.

http://www.spreadfirefox.com/?q=affiliates&id=199155&t=218

You may think Firefox is just a browser, but as a WAD you need a W3C compliant browser and Firefox is the leading development environment. The browser complies with almost every web standard, which every web application should initially be built against, before attempting to support non-compliant browsers. In addition, there are numerous extensions that can be downloaded to aid in development; here are a few:

FireFox 3
http://www.mozilla.com/en-US/firefox/all-beta.html

Download the Beta for the next version of FireFox and begin updating your website to support it. As of writing this, YUI has some known issues with FF3, but I expect these errors to be fixed in version 2.5.2 or higher.

Firebug by Joe Hewitt
http://www.getfirebug.com/ or
https://addons.mozilla.org/firefox/1843/

For the Mozilla Firefox browser, FireBug is the most powerful tool in a WAPs arsenal. With FireBug you can monitor AJAX requests, view and edit live CSS, delve into the DOM, mark breakpoints and step through JavaScript, and monitor HTTP requests all in one place. Since the release of version 1.0, FireBug has become my defacto development tool.

Venkman (Mozilla JavaScript Debugger) by James Ross, Robert Ginda
https://addons.mozilla.org/firefox/216/

This was the original FireFox debugger, a precursor to Firebug, and is also great for marking breakpoints and stepping through JavaScript code. I used to experience an issue with this extension where closing and re-opening it, would crash the browser. I am not sure if this is still true, as I have not needed to use this extension for over a year. I used to occasionally use it as a backup for or in parallel with Firebug (you can set breakpoints in each tool during an AJAX call, if the callback function might be executed more than once).

Web Developer Toolkit (WDT) by Chris Pederick
https://addons.mozilla.org/firefox/60/ or
http://chrispederick.com/work/webdeveloper/

This toolbar is filled with a lot of little features that increase productivity. Some of the most helpful features that make this tool indispensable are: live cookie editing, outlining elements by tag type, and resizing to browser to support different resolutions. Spend some time and get to know the features, and I am sure you will find something that you cannot live without.

MeasureIt by Kevin Freitas
https://addons.mozilla.org/firefox/539/

If you ever need to do anything with layout this tool will allow you to quickly measure page elements and white spaces. Although, I almost always just use FireBug, there has been occasion when FireBug did not report accurately or it is far easier to instantly select the area I want to measure, instead of adding dimensions from FireBug.

View Source Chart (VSC) by Jennifer Madden
https://addons.mozilla.org/firefox/655/

This is much more powerful than the standard ‘view the page source’, as it is more readable and includes elements that were rendered by DOM scripting and AJAX. Especially, useful if you want to see if an invisible element was actually added to the DOM.

Y-Slow by Yahoo, Inc.
http://developer.yahoo.com/yslow/

This is a simple tool that analyzes web pages and determines which, well-documented changes, you can implement to drastically improve the performance of your Web Application.

Internet Explorer (IE) by Microsoft

If you hoped you could simply develop in FireFox and call it a day, I am afraid you are very wrong. Although, it is far more efficient to not develop cross-browser, compliant applications in IE, you will need to support IE before launching your Web Application, as IE is the largest market segment. And to make matters worse you also should support the last few versions of IE, as many IE users are average computer users and often corporate computer users are mandated to use IE because of company intranets.

Microsoft Script Debugger (MSD) by Microsoft
http://www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94fd-4569-b3c4-dffdf19ccd99&DisplayLang=en
This is a must have for when you get to supporting IE (ideally, this will be one of the last steps in your development cycle). You can do a lot with script debugger, including JavaScript breakpoints and variable watching. Once you download the add-on, additional usage information can be found at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdbug/html/sdbug_1.asp

Fiddler by Microsoft
http://www.fiddlertool.com/fiddler/

See most network traffic in and out of your computer. This is useful for http request and AJAX monitoring in IE, although it seems to track more than just IE traffic.

Multiple IE (MIE) by Manfred Staudinger
http://tredosoft.com/Multiple_IE

You still need to support IE 6 for about 4-5 more years and this tool allows you to run an IE 6 instance without launching a virtual PC. With it you can see how your pages behave in IE 3, 4.01, 5.01, 5.5, and 6, without interfering with IE 7. The only problem I have ever encountered is a memory leak having to do with older IE versions and displaying elements with the opacity style.

IE Developer Toolbar
http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en

Although, it has a long way to go to replace the Web Developer Toolbar of FireFox, this is must-have tool for IE 6+. You can outline and hot-click on DOM nodes, view and navigate through the DOM, measure page elements, and more.

Internet Explorer 8 Beta

IE is getting closer complying with the standards every day. IE 8 is Microsoft’s challenge to FireFox, and the Beta looks better and better each week. By default IE 8 will be standards compliant, but Microsoft is introducing a new meta tag, to allow rendering in other versions of the browser (perhaps we will no longer need Multiple-IEs).

DebugBar for IE8
http://www.debugbar.com/download.php

This is the latest tool in your arsenal, combining IE Developer Toolbar and Microsoft Script Debugger to have a tool that is almost as powerful as FireBug. This finally makes IE develop efficient .

Other Tools

Opera 9 Developer Console
http://dev.opera.com/tools/

If you need to support Opera, you will occasionally run into JavaScript errors that are not triggered by other browsers. In better develop and debug in Opera, I have found this tool, incredibly useful.

Safari 3 Web Inspector
http://www.macosxhints.com/article.php?story=20030110063041629

This is part of Safari 3, and if you have not already upgraded, you will need it, in order to use this tool. This tool allows you to inspect the DOM, which is not as useful as tool in other browsers, but is very helpful if you want to support Safari. If you also need to support earlier version of Safari, I suggest you test and fix Safari 3 first, then run separate Safari versions installations and see if it is fixed, before trying to debug in those less hospitable versions.

JSLint by Douglas Crockford
http://www.jslint.com

Run JavaScript through Crockford’s tool before releasing to production and will help prevent many easy-to-overlook errors. Also, if your code validates with JSLint you can use a minimizing or obfuscation tool to reduce and protect your code.

JSMin by Douglas Crockford
http://www.crockford.com/javascript/jsmin.html

jsmin.exe < fileToCompress.js > fileToStoreCompressedJS.js

If you have more than 50k worth of JavaScript, then script downloading becomes an issue on dialup and some DSL modems (if you have more than 200k of JavaScript, then you might have issues on high-speed connections as well). To reduce script download times you can combine your JavaScript into fewer files, and then remove needless white spaces and comments from your production code. JSMin is a command-line application that usually reduces the file size by 33% and allows you to properly comment your development code-base, whilst hiding those comments from everybody else.

If you just have one JavaScript file or want to see an online compression tool, try:

http://www.brainjar.com/js/crunch/demo.html

CSSTidy
http://csstidy.sourceforge.net/

csstidy.exe < fileToCompress.css --template=highest > fileToStoreCompressedCSS.css

This is the CSS version of JSMin. Use this to remove needless white spaces and comments from your production code. Some online CSS minimizers are:
http://www.cssoptimiser.com/index.php
http://www.cssdrive.com/index.php/main/csscompressor/

YUI Compressor
target=”_blank”>http://developer.yahoo.com/yui/compressor/

YUI Compressor combines JavaScript and CSS compressor into one, easy-to-use tool. See the website above, for examples on how to use it. I now use this instead of both CSSTidy and JSMin.

posted by Matt Snider at 4:00 pm  

Powered by WordPress