Discord — React Native

Nigawad SreejaReddy
6 min readJun 25, 2021

--

What is Discord ?

Discord is a group-chatting platform originally made to give gamers a place to build communities and talk.

•But since its launch in 2015, it has branched out to include communities from all over the internet, ranging from writers to artists . It has boomed in popularity during the pandemic, as more people have worked, played games, and socialized online, and the platform says it now has more than 140 million active monthly users.

•It is built to allow members to message each other. Each community is called a “server.” If you’re familiar with Slack, you can think of it as a less formal version of that app.

•It can also be connected to other apps, like YouTube and Spotify. And there are both desktop and mobile versions of the platform, so you can use it no matter which device you’re using — even while you’re gaming.

What is JavaScript ?

JavaScript is a text-based programming language used both on the client-side and server-side that allows you to make web pages interactive.

What is JavaScript used for?

  1. Adding interactive behavior to web pages.
  2. Creating web and mobile apps.
  3. Building web servers and developing server applications.
  4. Game development.

When Is the Use of JavaScript Is Recommended?

JavaScript’s primary use is to transform web pages from static to dynamic.

  • Showing or hiding information.
  • Zooming in/out.
  • Displaying a timer or countdown.
  • Gallery carousels on homepages.

Is JavaScript Front-End or Back-End?

On the front-end, JavaScript works with the HTML and CSS to optimize web pages for the use. At the back-end, JavaScript positions Node.JS to manage data and handle user requests.

Advantages of JavaScript :

  1. Speed and Efficiency
  2. Simplicity
  3. Popularity
  4. Interoperability
  5. Interface Development
  6. Add-On Extensions
  7. Variability
  8. Upgrades

React Native:

React Native (also known as RN) is a popular JavaScript-based mobile app framework that allows you to build natively-rendered mobile apps for iOS and Android. The framework lets you create an application for various platforms by using the same codebase.

Why Discord is Sticking with React Native?

  • As soon as the React Native became Open Sourced , Discord used it to build iOS app from the core. The iOS app currently sees many millions of monthly active users, is 99.9% crash free, and holds a 4.8 star rating on the app store. This is achieved only with a team of three core iOS engineers.
  • At the beginning of the year , the team started to notice that the app had appeared to have degraded across several vectors(frame drops , battery drain, time to interaction etc ) . This app was originally built in 2015 and it performed quite well on iPhone 5s , which served as the baseline model. Now in 2019 , the app was clearly unusable on the four year old iPhone 6s. Even when using a top end iPhone XS , the app could not maintain 60 FPS in normal usage, provide smooth gestures , and had a noticeable impact on battery life.
  • So to overcome the above problems , they created a mobile performance squad , whose mission was to execute a deep dive into driving top tier performance on across all supported iOS devices.

Phase 1 : Flux Store Optimizations

Here , they first investigated on dataflow and they found that :

  • Every action that triggered an update to the user store— which holds the state of all known users — resulted in a 30ms emit.
  • The message load/cache restore actions — which directly result in processing and rendering the chat messages — resulted in a 500ms on an iPhone XS and 1000ms on iPhone 6s.

While neither of these actions were directly causing frame drops, they were clearly wasting a lot of CPU and battery.

Phase 2: React Component Optimizations

1.Commit Passes : The React commits could cost up to 200ms when affecting things at the higher levels of the component tree. On top of this, they were going through up to three commit passes when the app was starting up.

  • Commit passes was simple when React Native was released, there was no easy way to get the current dimensions of the screen so they relied on the very first render to trigger an onLayout which they sent to a ScreenStore for others to consume. React Native has since improved the Dimensions module by giving it more information and firing events when they change. We made a change so that stores could initialize with the correct data, avoiding multiple commit passes and even shrinking the view hierarchy. This actually shaved about 150ms off TTI since diffing the tree at the top level was not cheap.

2.Direct Message Rendering

3.Pure Component : A lot of engineers at Discord used to default to using PureComponent since it avoids renders if props don't change. Unfortunately, it isn't that simple .

  • Another thing not always clear to our engineers, was that style and children are just like any other prop and if you are passing a style as an array or dynamically creating style objects, you are breaking PureComponent, the same goes for children. Unless explicitly controlled, any children are just creating new components which never pass an equality check.
  • With the above in mind they did a pass over our most commonly used Component’s — removing unnecessary instances of Pure and minimizing their use of dynamic styles. All of this work resulted in about 30ms being shaved from rendering when doing common actions like switching channels.

Fast List : Lists have always been a headache in React Native. They actually implemented the core chat view natively because lists don’t perform well for many dynamic rows.

  • They replaced <Scroller> with <ScrollerView> and <div> with <View> and dropped it in. It worked! Right out of the box it performed almost as well as recyclerlistview and was able to use nearly the same code for rendering as the desktop app. Then they spent some additional time adding sticky header support and using some similar techniques employed by recyclerlistview to recycle views - avoiding allocations both on the React and UIKit side.
  • The result was a new component called <FastList>. The team intends to merge these together for cross-platform use and open source it for the community. With that they removed a lot of memory allocations and were down another 70-90ms of render time. It net resulted in over 100ms render time savings in common app usage patterns.

Phase 3: Main Thread Optimizations

Phase 4: Perceived Performance Optimizations

Phase 5: RAM Bundles

The Results :

  • Fluid gesture interactions for the core navigational system.
  • A fairly consistent 60 FPS across the supported devices and a very noticeable reduction in battery consumption.
  • A much better development experience since even the app under development mode runs much better than the production app before these changes.
  • An average of two seconds shaved off the initial load time.

--

--