Out of Hanwell

February 11, 2006

Browser Quirks and Managing Dependencies

Filed under: Uncategorized — Matthias Miller @ 5:41 pm

Developing applications for multiple platforms is particularly difficult. When the platforms behave identically, it is easy. When the platforms diverge (as they inevitably will), the developer is caught in the middle and must somehow bridge the two worlds.

This is a big problem for web developers, who are dependant on the many different browser implementations. Even high-quality software ships with defects. The trouble with browsers, of course, is that they may be used long after newer versions have been released. Web developers need to support these browsers, either by re-implementing features or downgrading behavior.

Although it may seem that using libraries keeps you from reinventing the wheel, using libraries brings on its own share of challenges. And if developers choose to use third-party libraries to expedite the development, they are dependent not only on the browser but also on those libraries.

First, a library may have bugs. If you’re fortunate, when you encounter a bug in the library, you can simply send a test case to the developers and receive a fix promptly. If you’re less fortunate, you may be able to debug the problem yourself and submit a patch to be integrated into the source. If you are not fortunate at all (e.g. the developers disagree that it’s a bug or the vendor went bankrupt), you’re left with a buggy library that you must either patch with every subsequent release or that you must constantly work around to avoid its problems.

By using a library, you increase the size and complexity of your project. Libraries can consume substantial bandwidth, which is a concern in certain situations. A library is a large learning curve for new programmers. Every dependency on a library is barrier to sharing your code with other projects.

You enter an upgrade cycle for your libraries. Some developers are committed to backward compatible releases, and others simply are not. If not, you can spend a lot of time replacing calls to deprecated functions. Although each new release brings many bug fixes and new features, it likely brings new bugs. Each release can come at a significant cost.

Whether you choose to use a third-party library, the goal is to protect yourself from changes in browser behavior. And if you choose not to use a third-party library, you are likely to develop a library of your own, and likely one that is better suited to your needs. Take, for example, a web business application that I am helping to develop. Even in its infancy, its user interface requires large amounts of JavaScript (the business logic remains server-side). Although we have chosen not to use third-party libraries, we’re doing two things to protect us from browser dependencies.

First of all, we are localizing assumptions about the browser. Many browser differences can be solved by DOM sniffing, but certainly some cannot. For example, when a user modifies form controls and refreshes a page, Mozilla restores the form values immediately. Internet Explorer, however, does not restore them until the page has loaded. This difference cannot be detected by mere DOM sniffing. Instead of proliferating browser checks throughout our code, we chose to abstract this knowledge behind a function call.

Secondly, we are testing our assumptions about the browser. Although we could use a third-party solution such as Selenium or jsAssertUnit, we have chosen to build out our own lightweight unit testing framework. Whenever a new version of a browser is released or if we decide to target another browser, we can run these tests to validate the basic assumptions of the web application’s environment.

Even with our abstraction and unit testing, we spent a lot of time manually testing our application in the recent preview release of the Internet Explorer 7 beta. But we spent our time looking for new classes of problems, not perusing our source code trying to fix that assumption in a hundred different places.

That’s what it means to manage dependencies.

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.