Dream11’s big bet on React Native
- Published on
In 2021, we started using React Native at Dream11. Two years and a steep learning curve later, we have fully migrated our front-end app from Native to React Native, positively impacting productivity.
We, at Dream11, thrive on providing world-class user experiences to sports fans. As the world’s largest fantasy sports platform with over 200 million registered users; a smooth, unbroken app experience is crucial. The stakes are higher during the IPL- the most-watched cricket tournament in the world. During the 2023 IPL, we managed user concurrency of over 11 million on our platform. Needless to say, our engineers work round the clock to keep the systems up and running to deliver the best experience.
The Dream11 app, powered by React native, is a critical and the most customer-facing component of the system. Moving to React Native was a big strategic bet and one of our most technically and organisationally challenging initiatives.
IPL 2023 saw the full migration, making it our first major sporting event powered entirely by React Native. In this article, we will cover why, among all cross-platform application development technologies, React Native was the best fit, and our gradual migration.
Why React Native?
Consistent user experience, parity across platforms and increased efficiency as a result of less duplication are inherent and well-documented benefits of any cross-platform technology such as React Native, Flutter, Kotlin Multi-Platform, etc. Besides the obvious benefits, our choice was influenced by the following factors:
Staffing
Our teams are structured to be self-sufficient with their focus areas and product offerings. Exponential growth in the online gaming industry in India meant the creation of many such teams. Building teams with all the necessary proficiencies was always a challenge. React Native opened up a large pool of Javascript developers for us, making it significantly easier to scale our teams.
Technological fitment
We were using Typescript to power our PWA, some of our backend services and the BFF layer (Check out how we optimized our GraphQL system). Production experience and In-house expertise helped us opt for Typescript as the primary language.
The popularity of React as an open-source project, combined with FanCode’s (a sports streaming & merchandising platform in the Dream Sports ecosystem) success in developing their mobile app on React Native further strengthened our decision.
So how did Dream11 deploy React Native for over 200 million users?
In this section, we aim to understand Dream11’s migration strategy and pivotal factors that influenced our decision to persist with React Native, despite initial setbacks.
Proof of concept
We introduced React Native in our app by developing a new feature called Streaks with a brownfield setup. It was released in April 2021 and met our hypothesis on a majority of our business metrics. The quality metrics of the app also remained largely stable.
Bootcamp
In the next phase, we were tasked with the responsibility of onboarding an existing team of Android, iOS and Web developers on the technology stack to familiarize them with the ecosystem.
In June 2021, we started a comprehensive training program - a mix of live sessions by in-house experts and some online courses covering topics such as Typescript, React, Developer Tools, etc.
Migration
By the end of September 2021, we had to make a decision - either to migrate the app gradually spanning several quarters or do a full-blown migration before IPL 2022. The latter was a moon shot but we went ahead with an aggressive migration plan:
- A gradual migration would have meant that all teams (in the interim) would need engineers with proficiencies in 3 stacks (Android, iOS and React Native) for product increments, adding to an already strained hiring pipeline.
- Because of the brownfield setup, the native implementations of all our features could co-exist as a backup, in case the React Native implementations did not perform as expected
Release
It was a colossal effort. By January 2022, we migrated ~80% of features to React Native.
While migrated features were functionally at par with existing implementations, we saw a deterioration in performance benchmarks. This caused a slight commotion in the tech, product, and design teams, especially with a marquee event like IPL just around the corner.
However, in February 2022, we decided to release React Native to a small set of users as a five-day experiment primarily because:
- Even though literature was available on how performance impacts the adoption and retention of mobile apps, we never really established this correlation specifically for our use case
- We wanted to test the new implementation in a relatively off-peak period to get production data with minimum risk
The experiment was not successful. The React Native implementation of features performed worse than anticipated. There was a clear degradation in user experience and quality metrics like load times, jankiness, crash rate, etc. We saw close to a 10% dip in business metrics such as revenue, funnel drops etc. for the cohort exposed to the experiment. This was extremely demotivating and caused skepticism around the migration.
Learnings & Revival
Even though the experiment was a crippling blow to the initiative, it massively improved our understanding of React Native. We will share our learnings with technical details in upcoming blogs. But, at a macro level, here are some critical ones:
Performance - As a first-class citizen
Any declarative UI framework relies on the system to generate views for a given state and concepts such as reconciliation to execute updates. Moreover, cases of high-frequency communication with the Native realm could also become a bottleneck. Such inefficiencies could bleed you with a thousand cuts and cause the user experience to be sluggish.
We conducted a thorough audit of all the features along with the base setup and came up with avenues to boost performance. Therefore, some optimisations we did to alleviate the problem:
- Reducing view re-renders through memoization, removing prop drilling etc.
- Using custom components with declarative APIs in cases of high-frequency UI updates. E.g. Timer, Animations etc.
- Leveraging the Hermes engine
- Deferring initializations or Lazily loading wherever possible
- And tons of micro-optimisations to keep the resource consumption in check
Benchmarking capabilities
“You can only optimize what you can measure”
Having the right tools to measure improvements helped us get faster feedback. We identified critical interactions on the app based on production data and wrote tests to measure vitals such as load times, frame rates and resource (CPU, memory, battery, network) consumption. Key tenets of these benchmarks were:
- Comparable: Ensuring test results are comparable across implementations (Native vs React Native) and different versions by identifying appropriate hooks/primitives
- Precise: Running a statistically significant number of iterations, based on the nature of the tests, to achieve minimum standard deviation
- Quasi-real: Writing tests that replicate user behavior and executing them on real devices with varying processing power, memory size, CPU architectures, operating systems, etc.
State of React Native
The React Native community is truly amazing. We collaborated with some core contributors and can confidently say that our journey would not have been possible without their guidance. However, navigating an evolving ecosystem presented its share of challenges:
- Predicting the stability of the app is challenging as some of the devices or operating system-specific crashes and ANRs are difficult to catch or reproduce in lower environments. E.g. It took us significant time to find a workaround for a crash in the Animation component taking place intermittently and on devices with Android 12 OS
- Achieving desired performance on screens with long dynamically changing lists is not straightforward. We tried tuning Flatlist to get optimal performance to develop the Chat module in our app. However, after multiple attempts, we ran out of improvement avenues and decided to stick with native implementation
- The much-awaited Fabric architecture optimized bridge communication between the JS and the native world by making it synchronous. However, while trying to find the root cause of performance issues on content-heavy screens in React Native (especially on low-end devices), we found that the render phase was eating out the most from the 16-millisecond budget of drawing a frame
Managing organizational friction
Moving to React Native meant a fundamental change in our development lifecycle, making it imperative for everyone to become cross-functional. This involved a steep learning curve and letting go of career-long technological affiliations.
Looking back, we should have opted for a gradual transition, providing everyone ample time to adapt, get comfortable and gain production experience.
Comprehensive rollout plan
Since fantasy sports are time-critical, users are accustomed to interacting with the app in a certain manner and are sensitive to even minute deterioration in app vitals. Thus, having a feature-wise rollout (& rollback) plan helped in gradually increasing exposure with confidence:
We leveraged our in-house experimentation platform & data analytics tool to A/B test Native vs React Native implementation by creating mutually exclusive cohorts for each feature
Milestones:
Stability test on randomly selected users to identify fresh Crashes and ANRs: 10k users
Business metrics test to identify funnel or revenue drop
- General users: 50k users in both Test Group and Control Group
- Power users: 10k users in both Test Group and Control Group
100% rollout of React native implementation if a) and b) are successful
The Results: Dream11’s React Native Success Story
By the start of 2023, React native implementation of features was exposed to almost all of our users after going through multiple cycles of optimizations. While many new product increments were baked in during the migration phase, there was an associated opportunity cost. Moreover, there was a tectonic change in the way the mobile app team operated.
As we approach the end of almost a year of full exposure, let’s assess how the migration fared for strategic objectives and whether it was worth it.
Hiring
Despite optimising our recruitment process from 2020 through 2021, our team grew gradually. However, as soon as we switched to hiring Javascript developers and utilized our training program, we expanded at a significantly faster rate.
In just about 18 months, the size of the mobile team crossed 100 developers.
Efficiency
A homogeneous app development team made it easier to spin off new product verticals and move developers more freely among teams. Moreover, having a single code reduced the associated maintenance costs.
However, a small caveat worth mentioning is that React Native adds a constant overhead to ensure stability and performance at par with Native.
OTA updates
One of the biggest advantages of React Native is Codepush. In the last year alone, we have deployed over 150 updates using codepush. It speeds up distribution by delivering updates over the air and is particularly helpful in reducing turnaround time in case of business-critical issues
Below is the graph, explaining the speed at which users adopt new updates when distributed organically, compared to nudging users to optionally update vs via code push:
Institutional awareness around user experience metrics
Going through rigorous iterations of experiments helped build a common understanding of app vitals among technology, design, and product teams. Reasoning about the impact of user experience metrics such as load times, crashes, and ANRs became easier as a result of having conclusive data to measure their impact.
Through the past year, we continued monitoring and finding avenues to improve user experience, reliability and developer experience with more focus and conviction. (We will be sharing our learnings in subsequent blogs)
Growth opportunities
Moving to a cross-platform technology had a major impact on team culture. We began measuring the quality of the software more objectively. Not limiting ourselves to a specific technology stack and embracing a problem-solving approach grounded in first principles raised the bar within the team.
Way forward
We have benefited greatly by leveraging the offerings from the React Native ecosystem over the past few years. As we move forward, one of our biggest goals is to engage a lot more and give back to the React Native community. We would like to write/talk about our learnings across various forums, dedicate time and energy to solving open issues and help in whatever way we can.
Stay tuned for more updates!
Authored by: Fenil Kanjani
Do get in touch:
https://twitter.com/fenilkanjani