Quantcast
Channel: Backstage - Medium
Viewing all articles
Browse latest Browse all 103

Modernising legacy web app

$
0
0

This is the journey of all the things we have done during our migration of our complex InGoMMT’s B2B portal (henceforth referred to as “Extranet”) for hoteliers to manage their listing. Originally the app was written in a mix of Backbone, jQuery and Underscore code served via Django Rest Framework, now it is in the process of migration to a full blown standalone ReactJS web app.

jQuery to React migration (not implying jQuery > React 😉)

First major migration

The first task that needed to be done was to migrate the Extranet code from the Django codebase into it’s own repo and deployment setup. This entire journey has been captured in my previous blog post.

Django Unchained… Literally…

Just to summarise, I am listing down the benefits that we achieved post this migration.

  • The obvious benefits of breaking down the monolith. Can now work on Extranet standalone and ship faster
  • One command to build them all — previously it was a mess with developer having to run a separate script for legacy and react code and commit the built files. With the help of some custom bash scripts we were able to consolidate everything into one single build command.
  • Benefits of Create React App — Babel, ESLint, HMR (yes, this was missing) and added Prettier on top of that too.
  • Benefits to the user — Optimized build process resulted in some size savings as well without making any change. PWA (although not fully utilizable since we still have legacy code shipping separately).

Another major Gotcha I’d like to call out here is that, even though our webapp is a Single Page App, we figured out a way to maintain hierarchy of HTML files that eventually gets combined to one. The how is mentioned in the above post.

Strategies to introduce React into legacy code

Simple Mount

Let’s start with the most easiest and commonly used way. In this, we create a container element in the HTML, and from our JS code we can do ReactDOM.render onto that element.

Conditional Mount

Now as you progress during your migration, you will end up in places where the screen you are trying to revamp will show up conditionally, including the mount point you have. In this case, you can make use of Event dispatches to render the React code. This pattern is pretty powerful to make changes in some part of the screen.

React in the driver seat

So now, with the mix of above strategies, we were able to migrate close to half of our application. But now we were missing a few things which is crucial to the development, as well as sanity of the whole code base as such.

  • We needed Global State (ex: Redux) to share data between React screens
  • We needed to add a new Route with nested routing, which wasn’t possible with the simple routing logic we had.
  • We needed to introduce deep-linking to existing sub tabs we had.

With the above requirements in mind, we decided to introduce React as the entry point of the application, and force legacy code run in some of the tabs instead of the other way around (current situation). With this, we can introduce React Router, and global state (via React.Context) at the top level.

Let’s look at how our web app runs
Old code flow vs New code flow

We need to talk about Hooks

During this migration we also have started to adopt React Hooks. And so far the experience of writing with hooks has been amazing🔥. Listing down things that we found beneficial.

  • We are now writing far lesser code compared to before
  • Our code looks more readable now with“effects” which majorly for us is to run our legacy code in certain places. They are invoked properly and cleanup after themselves too. This enabled us to not migrate legacy code but make it work within some of the routes in React.
  • The code is more readable to someone who is new to React since they don’t have to understand the intricacies of this
  • And we still haven’t gotten around to extracting commonly used code into custom hooks. 😶

Impact

Over the course of all these changes, I would like to call out the impact that we have delivered to the user. After all our commitment is to deliver the best user experience to our customers!!

  • Our web app initial load time has decreased from ~10s to just under 2s.
  • Our Daily Active Users (DAU) have almost doubled post the migration (compared to previous year data).
  • We have cleaned up about ~30k lines of legacy code which remained unused in our codebase. This includes CSS cleanup. Which means the incremental code runs & CSS paints are faster.
  • Previously we were loading all tab’s HTML upfront, now only the relevant tab code is run which is also contributing to the above mentioned reduction.
  • The codebase is now more readable than ever as the role of legacy code has been completely minimised. ReactJS runs the major part of the application.

Modernising legacy web app was originally published in Backstage on Medium, where people are continuing the conversation by highlighting and responding to this story.


Viewing all articles
Browse latest Browse all 103

Trending Articles