We had a problem. Facebook had just come out with the Like button, and had provided code snippets that allowed you to badge pages with Like counts. The problem was that it took a couple seconds for the number of Likes to load, and in some cases the resulting text was bigger than the allowable space, pushing it to the next line, and causing the entire page to shift down. Besides the layout issue, it caused a really annoying visible jitter a couple seconds after page load, in some cases causing a user to click in the wrong place.
But that’s ok, because we had some very clever engineers on the team. We decided to put the Like button into an iframe to control its effect on the page. This is where memory becomes murky, but over the next month(!) of pain I remember there being a need to put the iframe into another iframe, weird requirements for passing information up and down the Inception-like layers, trying to trick it into thinking it was on one page while actually in another, and so on. Every time we thought we were done, we discovered an edge case that caused everything to break down, and led us farther down the rabbit hole.
Sometimes, the problem was browser-specific. Other times, subtle code changes on Facebook’s side caused everything to break. Ultimately, we realized that no matter how clever we were, the probability that any solution would break due to uncontrollable factors would rapidly approach 1.0 over time. We ended up throwing all that work away, and eventually Facebook fixed the problem on their side.
There’s a time for workarounds, useful hacks, reverse-engineering, and truly creative solutions to weird problems. And when you can control all other variables – lock down a specific point version of a library, prevent external interactions, guarantee a user environment – then it can make sense to bring out the blowtorch, duct tape, and bubble gum. Michael Abrash has an incredible description of optimizing an inner render loop down to eight cycles, taking advantage of all kinds of crazy tricks specific to the 486 processor. And that’s ok – brilliant, really – but not the world we usually work in, especially on the web.
When you’re dependent on an external API; when your code runs in someone else’s virtual machine; when you can’t control the upgrade cycle; when your target platform is fragmented; when standards aren’t respected, or are poorly implemented; when the code just isn’t meant to do what you’re trying to make it do; when your solution is really cool (squee!), and you really really want to code it (two “really”s!); when you can feel the awesome power of your own cleverness – this is the danger zone, and time to get a second opinion before you start down a dark path of leaky abstractions, heisenbugs, and an endless state of 95% completion.