I recently came across these tweets from David K. Piano about code reviews:
Just a reminder that life's too short to reject someone's PR just because they did things differently than you would have done.13:04 PM - 31 Jul 2020
ā Does it work?
ā Does it fulfill business logic requirements?
ā Is it tested and do tests pass?
ā Did the linter/formatter do its job?
If so, š¢ it!13:07 PM - 31 Jul 2020
"But we have a coding style guide..."
If it's not automated (e.g., via a linter or formatter), you're either wasting time by manually enforcing it, or the rules are too arbitrary.13:09 PM - 31 Jul 2020
It reminded me of comments I used to make while reviewing pull requests a couple of years ago:
- Reorder imports by grouping them in "some-random-order-I-thought-it-was-correct"
- Donāt forget the trailing comma!
- Always use X
- Never use Y
- Avoid doing Z
Too often I was replicating ābest practicesā someone told me in the past or Iāve learned by reading a blog post like this one and Iāve followed them blindly without questioning why I was doing it.
However, none of those things were fixing bugs or adding value to the product. I was just making everyoneās lives a nightmare by nitpicking on small things.
Most of those comments could be easily fixed by using ESLint and Prettier. Some of them couldnāt but they were actually useless. Just because Iād do it differently, it doesnāt mean my way is better. As David Piano said, āif it's not automated (e.g., via a linter or formatter), you're either wasting time by manually enforcing it, or the rules are too arbitrary.ā
If I could go back in time and give any advice to my old self, it would be: "Hey, dude. Take it easy. Chill out a bit and focus on what's important."
But what's important?
In my experience so far, code reviews are useful for three things:
- Avoiding bugs
- Learning
- Teaching/mentoring
When we make a generic comment like āNever use Yā, weāre neither avoiding bugs nor using it as an opportunity for learning or teaching. Instead, we should be more specific to the current case:
I think we shouldnāt use Y here because explain your reasoning. It might cause a bug like this problem example. We could fix this by doing solution example.
What do I do now?
As a rule-of-thumb, I try to remember the following:
- Is my comment helping to prevent a bug? Then, itās also an opportunity for teaching. So, I try to answer the following questions: What bug is it preventing? Why does it happen? How can we fix this?
- I donāt understand this code. Then, itās an opportunity for learning: āIām not sure I understand this part. Please, could add some comments to explain your reasoning?ā
- I understand this code, it doesnāt cause any bugs but Iād use a different approach. I either leave it alone because it doesnāt change the end-result or I use it as an opportunity for both learning and teaching: āHave you considered doing describe your approach? I think it could help us add some benefits/metrics of your approach here. Thoughts?ā This way, I can both teach my approach (in case the other person isnāt familiar with it yet) and learn the reasoning behind not using it (in case that person is familiar with my approach but has a reason for not using it, which I might not have seen).
Real-life example
Some time ago I came across a PR that was fetching millions of items using async/await inside a for loop:
for (let post of posts) {
await doSomething(post.id);
}
My code review was something like this:
I think we shouldnāt use this for loop here because itās blocking the loop. Every post has to wait for the previous request to complete before making another request. This makes the request slower (feel free to run a benchmark and correct me if thereās a mistake in my calculations). We could fix this issue by doing the following:
const batchActions = posts.map(post => doSomething(post.id));
await Promise.all(batchActions);
This way, we're performing those actions concurrently, which results in a faster response. Please, let me know if that makes sense or is there something else Iām missing here.
The intention behind my comment was:
- Avoid a performance bug that could hurt the application.
- Explain why that issue was happening (blocking the loop).
- Give an example of what we could do to fix that issue.
- Leave it open to be questioned in case my metrics were wrong or I wasnāt seeing some other problem that made them use that solution.
Takeaways
Make sure your code review comments are actionable and actually adding value to the product. Donāt waste time on nitpicking things that wonāt change the end result. Does it work as expected and is it passing your CI pipeline? Then, move on.
Code reviews are meant to improve the product and speed up development. If theyāre slowing you down and hurting the team, then maybe itās time to review your practices. At the end of the day, ājust chill out and enjoy the ride.ā š