Artisan of Code

Friday, 29 April 2011

More is Less

When adding JavaScript to a small site or blog, most web developers will instinctively reach for jQuery, however, most of the time the issues they are trying to resolve could had easily been fixed, in far less than the 214KB jQuery adds to their uncompressed page weight.

DOM

A large amount of the CSS selectors used in jQuery scripts consist of a single id, tag, or class name, and this is just as easily accomplished with native API’s.

Todays browsers have near perfect support for getElementById, getElementByTagName, and getElementByClassName, with the latter being unsupported but easily emulated in older versions of Internet Explorer.

function getElementsByClassName(el, className) {
    if (el.getElementsByClassName) {
        return el.getElementsByClassName(className);
    }
    else {
        var elements = el.all ? el.all : el.getElementsByTagName("*"),
            regex = new RegExp('(^|\\s)' + className + '(\\s|$)'),
            result = [];
        for (var i = 0, l = elements.length; i < l; i++) {
            if (regex.test(element[i].className)) {
                result.push(element[i]);
            }
        }
        return result;
    }
}

Admittedly this does not look as aesthetically pleasing as the jQuery DSL but it is no any less readable.

// before
$("#status").html(status);
// after
document.getElementById("status").innerHTML = status;

Events

Once we have our DOM elements the next step is generally to bind events to them, this is not consistent across browsers, but fortunately the problem was solved a long time ago, and a well established polyfill can be found in the addEvent method graciously hosted by the QuirksMode Blog1.

// before
$(buttonElement).click(function(e) {
    alert($(this).html());
    return false;
});
// after
addEvent(buttonElement, "click", function(e) {
    alert(this.innerHTML);
    return false;
});

When it comes to events, it turns out the jQuery DSL does not really add much on top of the existing solutions.

AJAX

Normalizing the XMLHttpRequest object across browsers is also a fairly easy job, and there are countless blog posts dedicated to the subject, including a simple solution by PPK2.

// before
$.get("/ajax.php", function(data) {
    var el = $("#content");
    el.html(data);
});
// after
sendRequest('/ajax.php', function (req) {
    var el = document.getElementById("content");
    el.innerHTML = req.responseText;
});

Again the jQuery DSL adds little to the existing solutions, with the existing solutions adding very little to the page weight.

Effects

Depending on the target audience and the relevance of the effects, one could argue that they are better implemented as CSS3 transitions and transformations, leaving the slower browsers such as IE with a fast but less rich experience, but if you must have animations in IE, then this is one area where doing it yourself is probably a bad idea, and is best left to an effects library.

Conclusions

Before reaching for a library, we should fully evaluate the problem and ask ourselves whether the said library will justify its self? Are there more appropriate choices? And do we need a library at all?

© 2010-2012 Daniel Knell