loading...

The code can look awful

merri profile image Vesa Piittinen ・4 min read

Six years ago... oh darn, that is a long time... I wrote a POC. It was a simple React app that had some minimal stuff to work as a checkout. You know the drill. It is a POC. It will be shipped to production.

Eventually... it was shipped to production.

What there was

The old checkout was an integral part of a ecommerce site written in PHP. It didn't have anything fancy: each step worked pretty much as a regular form submission, and visual state changes on a few elements were reflected with a bit of jQuery. It was a bit awkward to use, but you could buy stuff with it.

The ecommerce site wasn't really an app of it's own either: it was a part of a bigger monolith. This meant a lot of the code in the ecommerce site used stuff that one really should not expose so close to the user. For example, you could find a call that returned pure database values in the very last view layer right before rendering HTML to user.

This was as things were in early 2014. Mobile phones hadn't become a big thing just yet and their usage on the site was near non-existant. But we did know a change was coming. So we started to think about a new responsive site which would access stuff via APIs. To spearhead we chose to make checkout first. The first few months went by as order logic was refactored so that it became possible to write an API.

React 0.13

This is a very early version and I think there are some things that need to be brought up. At this time React was somewhat known, but nobody hadn't really yet put effort into it. For the most part you didn't have much of useful documentation, like conventions were non-existant. You had to figure it out yourself. This didn't result into very nice code as the whole concept was new at the time, and React itself was very rough. The only concept for components was createClass and you had some odd stuff like mixins.

Redux was also still a thing of the future. This meant state management wasn't quite clear and the existing documentation on Flux didn't really convince one to make use of it. So we went without and lived by passing all data via props. Many components were rather big as well (and some are still to this day!).

This did mean there were some challenges with rendering performance. Especially people who added in stuff and didn't do React any other time could cause a noticeable delay to the UI.

But lets not get too far ahead of ourselves! The first usable feature implemented in the checkout POC was to let people in-house to make a pickup order from the local shop. The UI was a clean five step process with numbers on top of each step and progressing between the steps had a smooth horizontal transition. At this point most of the steps were practically empty since you could do just the one thing. But it worked and felt good.

So we kept it

We could have started from scratch with the new experience we had on React. We didn't. One part of this was my lack of previous experience on bigger projects, but the other part was the conceived robustness of the checkout. It turns out robustness won over code quality. Of course, we didn't yet know the intended way to do React.

Work on checkout's React frontend continued for a full year before release to public. All the shipping and payment methods had to be implemented, address management, cart management, thank you page. The typical stuff. Code quality didn't go up a great deal: if you'd look at the code of that time with today's knowledge you'd feel pain in every part of your body!

There was one thing that was kept in though: the perceived robustness of the UI. It was very hard to get the UI into a state where it didn't work. And if you're an experienced developer you know I lie right now. There is always a way a site breaks in Internet Explorer. Or mobile Safari. But please. Let's not talk about that.

Release

So you know the typical release of a software. You replace a feature with something entirely different, people are familiar with the old, and then they complain. A lot. The new checkout was visually clearly different from the old and didn't have a lot of recycled elements. You would expect to get the usual feedback.

We got to a point where we started progressing a part of customers to the new checkout in percentage chunks. 10% for a day. No issues. 25%. Nothing. 50%. Still nothing. 100%. Silence.

Nobody complained. Conversion improved.

We had the most awful code as far as prettiness and neatness is concerned. But the UI was clean, it made you go through clear steps one-by-one, you had one "unnecessary neat effect" with a horizontal page transition that aided you visually, and all the manipulation was robust.

One additional thing that might have helped us with the result is that we dogfooded the system to ourselves. All our own orders had to go through the new checkout during development phase.

Since then there has been improvements to the code and it does meet some further standards of today. Adding in Redux helped the most though as it greatly improved rendering. The thing is though: your code doesn't need to be the best when you're trying to ship something out. It is much more important for the code to work right. Do the right things for the user.

The API did what it should. The UI felt great. You have a success.

Posted on by:

merri profile

Vesa Piittinen

@merri

Web Front End Specialist who doesn't want to identify as Full Stack, but knows how to get stuff done. Loves perf and minimalism. HTML + CSS + Web Standards over JS. UX over DX. Hates div disease.

Discussion

markdown guide
 

I am a big fan of the "boy scout rule".

Leave the code better than you found it.

I don't see that you are advocating for writing bad code anywhere. Everyone here wrote the best code they could at the time. Things change over time and that's ok.

Legacy code that works, but is different, doesn't need rewritten. Unless there is a perf, UI, ux, or new feature leave it. But when time comes to touch that module/function/component make it better.

I wouldn't advocate for shipping bad code because you were to lazy or under a time crunch to refactor as you went. All too often I find folks swimming through an unmaintainable mess for days. 1hr of refactoring makes all the difference in the forward movement of the project.

 

I pity whoever has to maintain that code down the road.

 

I guess I didn't bring it up clearly enough, but improving code quality over time hasn't been neglected. There was a lot of maintenance done after release (such as the Redux refactor), and by React terms is only some two or three years behind the cutting edge for most of the code style. Reason for being even that much behind comes from being a separate codebase and the typical continuous lack of dev resources. It will eventually be integrated with the main site's codebase which brings stuff up to most of modern expectations and gives an opportunity to remove the remaining long time debt.