10 mins

Refactor Best Practices

Refactoring a mobile application can often be viewed as a complex process when it needn’t be.

Here’s some helpful steps to follow that will make the process smoother and more streamlined:

  1. Identify the areas that need refactoring: Start by reviewing your codebase and determine the areas that need improvement, such as poorly written, unused, or duplicated code, not forgetting code that is difficult to maintain.

To give you an example, we recently worked on an app that was running very inefficiently. It was checking for authentication every time it got a location update, which happened many times per second. This made the app very slow and caused continuous problems with logging in and out. We also discovered the app also had features designed later on in the build to work with this inefficient method. This meant the app was slow and regularly crashing from the number of authentication calls it was doing while trying to perform other tasks.

We added a simple refresh process to the app (negating the need to multiple reauthenification attempts that were occurring frequently) which meant the speed of the app increased rapidly and reduced crash rates.
Sometimes in development you have strict deadlines where you need to deploy your app. This can lead to shortcuts being taken. Revisiting your app to look for improvements can drastically improve your app’s performance.

Another example can be seen in our IMS case study where we reduced crash rates by 90%. We consolidated 3 codebases into 1 to make managing a suite of apps easier go check it out here.

  1. Prioritise the areas for refactoring: Once you have identified the areas that need refactoring, prioritise them based on their impact on the app’s performance, maintainability and functionality.

Prioritising work can be challenging as a refactor often feels like a mammoth task when looking at the whole piece of software. Breaking up the task into manageable chunks and ordering them in priority is key to success. We suggest tackling the tasks that are quickest to do and that will have the most impact on your app’s performance.By doing this, you can quickly show value to the team and stakeholders and get the most benefit possible.

As we talked about earlier, the whole task is usually quite large and can be demoralising for the team as well as being expensive for other parts of the business. By prioritising you can keep everyone onboard and results focussed from the beginning.

When time is of the essence, we also use analytic tools such as crashlytics to help us identify the quickest wins! We would highly recommend if you don’t have a tool like this in place you create a lightning release to add some. This will then allow you to collect performance data to see where to focus and also allow you to monitor ongoing performance.

  1. Create a plan: Create a plan for each area that you need to refactor, including the steps you will take, the tools you will use and the expected outcome.

Below is an example plan for refactoring code that you can tweak and edit to for your own needs.

  • You should identify the code you are refactoring.
  • Define the goals for this piece of work.
  • Write tests for this piece of code.
  • Analyse the code for areas of improvement or issues such as duplication.
  • Prioritise work within the process.
  • Refactor code according to your priority list, make sure you test changes.
  • Repeat above steps until goals are achieved.
  • Commit changes to version control to be reviewed and tracked.
  • Document changes made so others can see the improvements made and why.
  1. Create a backup: Before you start refactoring, create a backup of your codebase so that you can easily revert to the previous version if something goes wrong.

Sounds like common sense but this step can easily be missed and have catastrophic consequences!
Remember: Not every change is an improvement, sometimes it has the opposite effect, and if you can’t easily revert you can be caught with those proverbial pants down and have even more work on your plate!

  1. Refactor one area at a time: Avoid introducing new bugs or breaking functionality in other parts of the app by only focusing on one area to refactor at any one time.

If you implement multiple things at once you won’t truly know what has made the difference or which things have caused an issue meaning unpicking the work you have done in multiple areas. By breakinging the app refactoring process into smaller chunks you can also have a quick iteration cycle too as there are less dependencies. With this approach, you can expect to see improvements in every sprint or release

  1. Write tests: As you refactor each area, write tests to ensure that the new code behaves correctly and does not introduce new bugs.

While it’s considered best practice to write tests for your code, not everyone follows this rule. However, during a refactor, it’s crucial to do so because the app is live and any mistakes could cause serious issues. To help you out further, here are some quick tips for writing tests for your code.

  • Write code that is easy to test. This means that the code should be modular, with clear boundaries between components. This will make it easier to write tests that verify the behaviour of each component in isolation. Tests should be small and focused. Each test should verify a single behaviour or function. This makes it easier to isolate and fix issues when they arise.
  • Use descriptive names for tests and test functions. This makes it easier to understand what each test is testing, and makes it easier to diagnose issues when tests fail. Use a testing framework to manage and run your tests. A good testing framework will provide tools for setting up test fixtures, running tests, and reporting test results.
  • Use assertions to verify the behaviour of your code. Assertions are statements that verify that a certain condition is true. If the condition is false, the test fails. Use mocks to isolate your code from external dependencies. Mocks are objects that mimic the behaviour of external dependencies, allowing you to test your code in isolation. Run your tests frequently, ideally after every change to your code. This will help you catch issues early, before they become more difficult to diagnose and fix.
  1. Test thoroughly: Once you have completed the refactoring process, test the app thoroughly to ensure that it still functions correctly and performs well.

The testing above is only half of the process. Writing code tests is incredibly important to protect the stability of your code but we believe that live testing is still required. Having a hybrid approach of automated testing for simple functions and then some hands-on testing to really focus on the user’s journeys is required with all refactor processes. It is so important that critical paths are tested with every release and that full test sweeps are carried out at regular intervals to make sure nothing slips through the cracks. Afterall the objective is to target improvements.

  1. Review and optimise: After testing, review the app’s performance and optimise it further if necessary.

Refactoring as mentioned above is an iterative process. Once you have “completed” a refactor, review your work. Look at what improvements have been made and congratulate your team accordingly.

Never get complacent though. With refactoring, there will always be more to do. At times, you may reach a point where you are satisfied with your app’s performance and can take a break. However, due to the rapidly evolving mobile landscape, frequent device releases and operating system updates, new feature introductions, you may observe a gradual decline in your app’s performance over time.

This unfortunately is the nature of app development at the moment. We regularly perform tests on our apps several times a year to monitor their performance and after a period of time more refactor steps are required. Regularly reviewing your app’s code to make incremental improvements is considered a best practice, as it can help prevent the accumulation of larger, more daunting tasks in the future. This brings me to my final step:.

  1. Repeat as needed: Refactoring is an ongoing process, so be prepared to repeat these steps as needed to maintain the app’s performance, maintainability, and functionality over time

This might not be what you want to hear but refactoring work never ends. It should become manageable and less daunting overtime but if your app is core to your business then you will always need to be revisiting and improving its performance. It’s possible that in the future, the mobile landscape will resemble that of the web. However, for now, it remains a highly volatile area in technology, and we can only wait and see how it evolves.

Overall, refactoring a mobile application can be a time-consuming process, but it can also greatly improve the app’s performance, maintainability, and functionality in the long run.