When Rewriting Your Software Doesn’t Matter

Imagine coming to work on a Monday morning, full of energy after a relaxing weekend, and it turns out you have an empty todo list. “Hell yeah,” you might think. “Finally, I have some time to rewrite that XYZ module. After all, it’s just a piece of crap.”

Wait. Think for a second before digging into that 8-hour task.

Will your customers see any difference? No? Then you’re probably planning to waste the whole day on trying to convince yourself you’ll do a good job today. But the reality is it won’t be a good job at all.

11-year-old JavaScript code

Here’s a textbook example of why you shouldn’t touch things that still work as intended.

LiveChat’s tracking code is just a snippet of code our customers install on their websites. It’s responsible for loading our chat widget (you can see it in the bottom-right corner) and exchanging some data with our server.

Seems like an easy task, right? I bet there’s a jQuery plugin for that ;-)

However, we’ve been in the business since 2002, and those were the days when JSONP and AJAX calls were like landing on Mars. Exchanging data between the web browser and the server was a tough task in these days. That’s when one of our developers came up with a smart idea.

He used the <IMG> tag’s attributes to exchange the data. The <IMG> tag was supported by all browsers so it was a very reliable solution. It worked the following way: web browser was “asking” the server if it has any fresh data available by loading a raw image:

var image = document.createElement('img');
image.src = 'http://server.livechatinc.com/12345/control.cgi';

When LiveChat server wanted to send some information to the browser, it returned an image with specific width. For example, a 32px-wide image. The browser was able to read the image’s width. It also knew that each <IMG>’s width represents a particular message. The width of 32px meant that a chat with an agent has started:

if (image.complete === true) {
	var w = image.width;
	if (w === 32) {
		// here's the code responsible for displaying
		// chat with an agent inside the chat widget

That’s how it worked. The data between the web browser and the server was exchanged using an <IMG> tag’s width attribute.

The most important fact is this: our tracking code still works that way. That’s right. It’s 2013 now and we haven’t changed that logic for 11 years. Our 6000 customers are using a script that exchanges the data using <IMG> tag’s width attribute.

Think about that. This code:

  • does exactly what it should,
  • works on all browsers; after all, it worked on all the browsers in 2002, too,
  • is a time-tested, bug-free solution.

Sure, we could rewrite that code and use JSONP to exchange the data. But the end-user won’t tell the difference. So what’s the point? We just focus on other tasks that really make a difference.

Be productive instead of busy

There’s a great quote by Tim Ferriss who says: “Focus on being productive instead of busy.” To better understand what he means, just have a look at some examples:

You’re busy when…

  • … you’re checking your mail for the 4th time within an hour,
  • … you’re sitting on a meeting lasting 60 minutes, whereas the conclusions could be laid down via e-mail in 10 minutes,
  • … you’re rewriting your app and the end-users can’t tell the difference.

You’re productive when…

  • … you’re designing a feature that will solve a problem that your customers are facing right now,
  • … you’re reading a book that will endow you with additional skills,
  • … you’re optimizing an algorithm which will result in 2x faster website loading time.

Refactor, don’t rewrite

Joel Spolsky wrote a great article about that “single worst strategic mistake that any software company can make: rewrite the code from scratch.” It’s a 13-year-old stuff that’s still a must-read for all software developers. Have a read if you’re thinking of rewriting the software: Things You Should Never Do, Part I.

Categorised in:

  • Adam

    Great job! I’m goin’ to print it.

  • axe_tester

    “But the end-user won’t tell the difference. So what’s the point?”. That is so valid in some cases. It is both true in developing and in testing.

    It’s better to take your time with something that is actually noticable – e.g. quality of the response rather then how the response is created.

    Obviously security issues are always to be looked into but other then that, if the code is safe, it’s good to be focused on the outcome visible to user.

  • 3dc

    Veto! :-)
    Code is written once but read multiple times. Therefore investment in writing it good pays of because it shortens read-and-understand-time (the bigger project the faster if pays of). It is hard to make code good from start, thus constant refactoring is required to produce high quality components. This also bring benefit of making code reusable and identifying needs and possibilities of reuse. In end effect this saves time and money, because code is simpler, shorter, not fragile, easier to understand and contains no repetitions. This makes introducing new changes simple and effective.

    All this applies assuming that software you delivering will be maintained, changed, developed beyond initial release. If it is small write-and-forget kind of project this is possible that effort put into quality will not pay of.
    But consider, that project not needing maintenance is highly unlikely scenario. Even if software is created without foreseeable maintenance effort it will most probably appear sooner or later.

    Code quality matters, it leads to saving time and money.

    I have strong feeling that you did not get right idea from Joel’s article. He is criticizing greenfield approach to systems as a whole, but He also writes:

    “The old mantra build one to throw away is dangerous when applied to large scale commercial applications. If you are writing code experimentally, you may want to rip up the function you wrote last week when you think of a better algorithm. That’s fine. You may want to refactor a class to make it easier to use. That’s fine, too. But throwing away the whole program is a dangerous folly”.

    This is because scale matters. Rewriting projects from scratch is not working. Rewriting or preferably refactoring components, classes functions, features does (this is what constant refactoring is about).

    And final word: will your customer feel the difference? Of course yes! Next feature or modification you will implement in few hours instead of days. This is how you beat you competitors.

  • Bartosz Olchówka

    @3dc: I’d like to distinguish two situations:
    1) refactoring of something that we’ll work on soon,
    2) refactoring of something that won’t be touched anyway.

    The article explains the 2nd situation. As our code needs to be very stable on production environment (other companies’ success often highly depend on our software), we’d rather not break down our script.

    During 11 years the code didn’t need to be modified (besides adding another “variables” sent through IMG tag), and refactoring seemed too risky. In the mentioned case, refactoring wouldn’t result in implementing other features faster.

    Same goes to space ships software which still runs Fortran because it would be way too risky to touch it.

    All in all, I agree with your points. Oftentimes refactoring your code is very important. I don’t argue with that. I just wanted to show you a perfect example of a case that, in my view, didn’t need to be refactored for many years.