My most recent work originally started as just a small tweak to refresh some styles and achieve a more uniform look. As Budgetwise gets closer to the v1.0 release however, I knew that now was the best time to go in and change all of the things I had wanted to before, but held off on for the sake of feature development. This post will go over some of the changes and improvements I'm making, and what Budgetwise will gain from it. If all goes well, this next update should come out a couple of weeks from now.
Note: This post will be technical, but I will try to break things down so that hopefully the general concepts will be conveyed even to non-technical readers.
The Steady Rise of Tech Debt
The very first version of Budgetwise, in November 2017, was extremely rough and lacking countless features. Gradually as I developed more features, the codebase got bigger and bigger but never really organized. The client folder structure consisted simply of:
/img /src /action-creators /reducers /store
And that's it. Every single file that didn't fit into those three redux-related subfolders were just kept in the root
/src folder. On it's own this was a considerable source of tech debt because you now had dozens and dozens of files to scroll through in a single folder.
After much deliberation and planning, I opted to follow a file and folder structure very similar to what Charles Stover suggested in his excellent post "Optimal file structure for React applications".
By the time it launched in July 2018, the features were being focused on so much that the project gained tech debt at an even faster pace. Here is what the
<Budget /> component looked like, for example:
So, right away there are a few red flags. For starters, there was a bunch of extra stuff being passed in like payees, subscription details, and accounts. Because React by default re-renders the component (and all of its children) when a prop changes, you were essentially re-rendering every single component and subcomponent in the budget screen whenever you added a new account. That's just one of the many examples that I found going through the code where components were getting needlessly re-rendered.
There were quite a few instances where I found that several different components were crunching the same numbers and running through similar functions to get a total like you see in the budget rows. These are being extracted out to a single memoized calculation using Reselect to greatly improve performance and cut down on repetitive code.
As an added bonus, these types of changes will cut down on bugs as every component will be getting the numbers from a single source instead of doing things individually.
After the grueling process of splitting up the files in a more sensible manner and restructuring the code, I ended up with much smaller, more concise components:
Among other things, one area in particular is getting lots of love - the menus. There were simply too many different areas to manage your budget and account, so I've consolidated many of the most common tasks into one submenu:
Adding Dark Mode
No screenshots of the dark theme yet as it's still under development, but stay tuned! ;)
Typescript and Improved Test Coverage
At the time I started Budgetwise, I wanted to add stronger typing through either Flow or Typescript but there wasn't a clear winner in terms of industry adoption. I decided to hold off and wait a bit as I didn't want to do the work twice, and I'm glad I did.
Today in 2019 it's becoming more apparent that Typescript is coming out on top, and even Facebook's internal teams are starting to move away from its own Flow towards Typescript. Now that I'm diving deep into refactoring the codebase, I will be adding in Typescript as well. The app as a whole will benefit from being strongly typed instead of dynamically, and will force me to think more about how I write code.
As for test coverage, I'll admit this is an area that needs improvement both in terms of unit tests and end to end. The problem with sticking to a strict TDD workflow at the beginning is that for very young projects, especially as a solo developer at the time, you may pivot or revamp entire features several times over before you arrive on the solution that works best.
Now that the features are solidifying and the structure/logic everywhere is being modernized, I am going to be focusing on adding improved test coverage through Jest and Cypress.io and spotting bugs before they get shipped out to production.
All of this work will go a long way towards getting it ready for the version 1.0 release (no official release date yet), and make it easier to add each upcoming feature without worrying about regressions. Once this update is out, I believe many users who may have stopped using Budgetwise due to persistent bugs or odd behaviors will want to check it out again, and churn rate will continue to decrease.
Thanks for reading, and please email me if you have any questions, comments, or concerns!