Readability vs performance

In some situations, performance needs to be at the core of a product. Programs dealing with very high traffic or interacting with critical real-time systems need that focus on performance. On the other side, regular websites and small internal systems with low traffic usually don’t need to be super picky about performance. If you are one of the few who works on a critical system where every millisecond counts, you can obviously disregard this section. Computers are so fast nowadays and can do so many operations per second that the performance boost you get by reducing code size or using tricks to make the code a little bit faster is marginal and won’t make a big difference. For those familiar with the Big O notation, I’m not talking about logic change that would allow you to go from factorial ( O(n!) ) to linear ( O(n) ) since those can have a huge impact on performance and can usually be done without impacting readability. I’m talking about minimal performance improvements like not storing a value in a variable or mutating the reference object so we don’t have to make a new copy. Those micro-optimizations usually don’t matter unless you’re doing thousands of operations per second. By focusing on readability instead of spending time on those optimizations, you can greatly increase the maintainability of the codebase ( and the team output ) while reducing the risk of errors, which will be more beneficial in the long term.

Early returns strategy

Early returns mean that we want to get unwanted situations out of the way first. It will allow us to reduce the number of indentations in the code so we can keep it as flat as possible. It’s making the code easier to read and removes some cognitive load since you don’t have to keep track in which condition context you are when writing or reading the code. It also forces a better control over the function output since you have to be more explicit about the return status for each condition by putting them first.

Don’t try to look smart

It’s best to avoid complex one-liners. You are not part of a code-golf.

Naming is hard

You might have already heard the popular saying

Size Matters

Sometimes smaller is better! Let’s take a function size as an example. The longer it gets, the more complex it becomes. There’s a principle called single responsibility that really helps to avoid those issues. As much as possible, a function should do only one thing but to do it well. Keeping a function simple will also have the side effect of being easier to unit test and make the code more robust.

Stay Consistent

Consistency is key when we want to keep a whole codebase readable. Enforcing it manually can be tough, but fortunately, there are plenty of tools that can help. A code linter like eslint and a code formatter like prettier can be used as part of a team arsenal to automate the process so people can focus on more important things and stop arguing about personal preferences like using spaces vs tabs.

Types are your friend

If you worked with strongly typed languages before, you probably don’t need to be convinced. There’s a good reason why there’s a team working on Typescript to bring types to JavaScript. Types can give additional context about the input/output of a function, especially when working on code that is unfamiliar. Having the definition of the parameters received in a function makes it easier to understand what’s going on, especially when we receive complex objects or a collection of data. The same concept applies to the function output. In most cases, Typescript can infer the output of a function based on the code itself, but writing down the input and output typing first when creating a new function will define the contract from the start, putting the focus on the logic inside that function. Additionally, types also have the benefit to add living documentation. There is some downside to typing though since it will add some complexity to a codebase and your code will need to be transpiled back to JavaScript.

Adding comments

Good code should be self-documenting. If you have to explain what’s happening, it usually means the code is not clear enough and could be improved. Sometimes, the logic has to be complex by nature, so it’s not always possible to simplify it enough. Adding a small comment in these situations can go a long way.

Quick tips

  • Avoid nested ternary since it’s making it more difficult to see the separation between multiple ternaries.

  • Avoid abbreviations for a variable name. Ex: firstName instead of fnamepassword instead of pw.
  • Don’t try to write ninja code.

Conclusion

Ideally, features would go from a prototype phase ( making it work ) to a productized phase. In a professional context, speed tends to be highly prioritized for external or monetary reasons, often cutting short the feature development at the prototype phase, or in an unfinished productized phase. It can lead to a lack of vision in the long term and can become really problematic as a codebase grows. Writing code, as well as other forms of writing, is hard. It takes time and experience to be able to write clean code, especially in a larger codebase. This responsibility should not land on the developer’s shoulders only, the whole company needs to be on board. This means that communication with other team members is very important and is something that needs practice and should be nurtured.