Migrating a large, high-traffic application to a new technology stack can be a daunting task. UI frameworks and tools have exploded in numbers giving us both the freedom and paralysis of too many choices. If you are reading this blog, you are probably leaning towards React JS.
React is a robust framework with a diverse, helpful community of developers who are always available to resolve your queries. In this blog, you will read about some of the best practices that our teams have gained from migration projects while working for some of the biggest retailers in the United States. While the focus would largely be on jQuery to React JS migration, most points will serve you even if you are coming from another framework, such as Backbone, Knockout, or Ember JS.
In a large application, it is prudent to follow a component-based architecture, i.e., split an app into smaller apps that can be deployed independently. For a retail website, for example, instead of creating one React app that spans the entire website, you can break it into separate smaller apps, such as search and browse, product, bag, checkout, order history, returns, profile, and more. These can be further divided into reusable functional components (e.g. header, footer, recommendations, product carousel, etc.)
This migration approach is useful even if you have the budget and resources to migrate the entire application in one go. The advantages are listed below:
With smaller applications, each of them can be scaled independently that can also save infrastructure costs, which is otherwise wasted in scaling the whole application. It also insulates different parts of the website so that if one section goes down, the others continue to serve requests.
Appropriate tool helps in structuring and building the app. Create-react-app (React Command Line Interface (CLI) for creating application) does a pretty good job of covering everything from scaffolding the app and code transpilation for ES6 and JSX, to configuring webpack for builds and module loading. Customizations should be identified early in every implementation.
Before the CLI is handed over to the development teams, the UI architects must create a complete 'Proof of Concept' application with unit tests, monitor the performance, deploy to a server, and load the page in a browser. Later, they must inspect the files that are being loaded to see if they need to be split up or combined, caching rules that need to be set, etc.
It is essential to have well-documented coding standards and conduct initial hands-on coding sessions with the teams to set expectations before they start with the development process. Assign points of contact for each team to resolve queries. Start with a small group of code reviewers who work with architects before opening up code reviews to individual teams.
It may be tempting to try and reuse most of your existing code to save the resources, but understanding what to let go can help you accurately estimate efforts required to avoid disappointments in the long run. If you are coming from jQuery, you must discard code related to the Document Object Model (DOM).
React uses an entirely new way of declarative data binding that requires the writing of code from scratch. Here are the areas that you can look to salvage your old codebase:
A change from jQuery to React JS isn't just about swapping one UI library with another—it is a paradigm shift. React-like frameworks mark a change in how we structure large applications for faster performance and easier maintainability of code.
Around the year 2005, when JavaScript libraries were becoming popular and the newer web browsers were becoming more efficient at running JavaScript, developers started moving a lot of logic that used to be traditionally handled by the server-side code to the client, i.e., the end user's browsers.
With the advent of single-page apps around 2010, routing, maintaining state, fetching, and manipulating data were all added to the laundry list of things that JavaScript would execute—all on the browser at the expense of the user's computing resources. This led to bulky applications that took a long time to load, stuttered during use, and drained the user's batteries.
Today, we know that a page that takes even a few seconds more to load costs a company money in lost conversions. Discoverability is dependent on the speed — Google ranks faster sites higher on its search results. Hence, the current push is to create UIs that load quickly and remain responsive to user inputs. To achieve this, an API must provide the UI with data in a render-ready format.
Here are a few examples:
The side effect of tailoring API response to a page's requirement is that the same API can't be reused on multiple pages. There can be various solutions to this problem. A simple one would be to pass a page name to the API, which can be used to customize the response. Another solution is to create a middle API layer (sometimes called the API Experience or xAPI) between your existing API layer and UI layer. UI will call the xAPI and not API layer. The xAPI will call your existing APIs to fetch the data, format the data as per the requirement of a particular page, and send it to UI that is ready to be displayed.
When you migrate to React, keep the API layer changes in mind while estimating the work involved.
Here is a list of few technical aspects that we have found helpful in our experience. While all may not apply to your use case, you can use the ones that hold relevance for you.
Each component will have its own repository with its dependencies declared in the package.json manifest file. When a developer wants to include a component in another component, he can install and use it in his code, just like the use of third-party NPM modules.
Often when components reside in the same codebase, they start as clean and modular, but over time, as more and more developers work on them, developers start depending on the internal logic of those components. This is bad because when the time comes to change some internal logic of a component, it may break other components that depend on its implementation logic. Setting up separate repositories for your components will force you to keep different components independent.
In our experience, migrating to React from other JavaScript libraries is more about changing the way we think about the front-end rather than learning a new framework. Yes, it can take developers some time to learn about the tools that React provide, but thankfully, it is just plain old JavaScript done right.