The React Native Basics That Would've Accelerated My Journey - Part 1
Essential React Native Concepts for Quick Learning
Table of contents
1. Is React JS and React Native the Same?
Despite both having React in their names, React JS and React Native serve different purposes. React JS is a JavaScript library for building user interfaces, primarily for web applications. On the other hand, React Native is a framework for building native mobile apps using React and JavaScript. The key difference is their domains: React JS targets web browsers while React Native targets mobile platforms.
2. Understanding React JS: The Role of DOM & Virtual DOM
To understand React JS, one must first understand the Document Object Model (DOM) and Virtual DOM. Let's explore how it works in React JS, React Native and compare it with Native Mobile Apps.
Virtual DOM in React.js:
What it is: The Virtual DOM is an in-memory representation of the real DOM elements. It's a lightweight copy where React keeps track of changes in the UI before making any actual DOM manipulations.
How it works: When the state of an object changes, React first changes the object in the Virtual DOM. Then, it compares the updated Virtual DOM with a pre-update version and calculates the best way to make these changes to the real DOM. This process, known as "diffing," minimizes direct manipulations of the DOM, which are costly in terms of performance.
Virtual DOM in React Native:
Transfer to React Native: React Native doesn't use the HTML DOM; instead, it has native views. However, the concept of the Virtual DOM still applies.
How it works: React Native translates your JavaScript components into the native counterparts of iOS and Android. When a component's state changes, React Native uses the Virtual DOM to determine the most efficient way to update the native views.
Performance Benefits:
Batched Updates: React Native batches multiple virtual DOM changes together to minimize native-to-JavaScript communication, which is relatively slow and costly in terms of performance.
Reduced Native Calls: By calculating the minimal set of changes, React Native avoids unnecessary view updates and interactions with the native side, speeding up the app.
Comparison with Native Mobile Apps:
Direct Manipulation: Native apps directly manipulate the UI views and components without the need for an additional abstraction layer. This can lead to smoother animations and transitions.
- Performance: Native apps generally have the edge in performance, especially for graphics-heavy applications or those requiring significant device interaction. They have direct access to all device APIs and hardware features without any bridge or layer in between.
3. The Power of Components
Components are the building blocks of any React application. They encapsulate behavior and rendering logic, making your code more readable and reusable. Here's a simple code snippet of a React component:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Components help in breaking the UI into independent, reusable pieces, and thinking about each piece in isolation.
4. React vs. React Native: Understanding the Differences
While React JS and React Native share common principles, they differ significantly in their implementation. React JS uses HTML and CSS for rendering, whereas React Native uses native components. Here's a small code snippet to highlight the difference:
React JS:
<div className="app">
<h1>Hello, world!</h1>
</div>
React Native:
<View>
<Text>Hello, world!</Text>
</View>
5. Is React Native Fully Native?
React Native compiles to native app components, allowing you to build genuinely native applications with JavaScript. However, it's not "fully" native as it bridges JavaScript and native code, which can occasionally lead to performance bottlenecks.
And It doesn't convert JavaScript into Java/Kotlin or Objective-C but bridges JavaScript code to interact with native APIs and components.
What's "Native" in React Native?
UI Components: React Native has a set of core components that map directly to the native platform's components. For instance, a
<View>
in React Native translates to a UIView in iOS and an android.view in Android. Similarly, a<Button>
in React Native renders as a native button on both platforms. This is the "native" part of React Native - the UI components are actual native components, not HTML elements.Performance: By using native components, React Native can leverage the native rendering engines of the platforms, leading to better performance compared to traditional hybrid apps (which typically use webviews).
Native Modules: React Native allows developers to write their own modules in native code (Java, Swift, Objective-C). These modules can do anything a native module can, from handling complex animations to accessing the device's hardware.
What's Not "Native" in React Native?
JavaScript Core: The logic of a React Native app is written in JavaScript, which runs in a JavaScript engine separate from the main UI thread. This means that the business logic, state management, and application structure are not "native" in the traditional sense.
Bridge: React Native uses a bridge to communicate between the JavaScript and native sides. This bridge is asynchronous and batched, which can lead to performance bottlenecks in highly interactive or real-time apps.
6. Architecture of React Native: Old and New
Old React Native Architecture:
JavaScript Thread: Where your JavaScript code runs. It handles the application logic, API calls, and state management.
Native Thread: Where the UI is rendered. Native components live here.
Bridge: The communication layer between the JavaScript and Native threads. When a JavaScript component needs to be rendered, or a user interacts with a component, this information is sent across the bridge to be processed on the native side.
New Architecture:
JSI (JavaScript Interface):
JSI is a lightweight API layer that allows JavaScript code to interact more directly with native code. It replaces the need for the traditional bridge by enabling synchronous calls between JavaScript and native.
This means that instead of sending serialized data across a bridge, JavaScript can hold references to native objects and execute operations on them directly. This can significantly reduce the communication overhead and improve performance.
Fabric:
- Fabric is the new UI layer that uses JSI to synchronize the JavaScript and native view hierarchies. With Fabric, the rendering process can be more efficient, and updates to the UI can be executed synchronously when needed, improving responsiveness and reducing lag.
TurboModules:
- TurboModules are the new way of building native modules in React Native. They also leverage JSI and allow for more efficient and lazy loading of native modules. This can lead to faster app startup times and overall improved performance.
Potential Improvements with the New Architecture:
Performance:
By reducing the reliance on the bridge and enabling more direct communication between JavaScript and native, the new architecture can significantly improve performance, especially in areas sensitive to round-trip calls.
Synchronous execution can make interactions feel more responsive and reduce the perceptible lag in UI updates.
Simplicity and Efficiency:
The new system simplifies the interaction model between JavaScript and native, making it easier and more efficient to build and maintain complex features.
It can potentially reduce the overhead of adding new functionality and improve the developer experience.
Flexibility:
- With more direct control over native components and the ability to hold references to native objects from JavaScript, developers can have more flexibility in building sophisticated features.
7. The Emergence of React Native SKIA
React Native Skia is a rendering engine that provides an alternative to the traditional way React Native renders its components. It's built on top of Google's Skia graphics library, which is the same library used under the hood by many systems, including Chrome, Android, and Flutter. React Native Skia is designed to offer more direct control over the graphics pipeline and potentially improve performance and customization for complex animations and UIs.
How React Native Skia Works:
UI Computation:
In a typical React Native app, the UI layout computation happens in the JavaScript thread. Components are defined in JavaScript, and their layout is calculated based on the styles and the component tree.
With React Native Skia, the UI descriptions and computations can still begin in the JavaScript thread, where you define your Skia-based components and their properties.
Rendering and Painting:
Traditional React Native: The computed layout and styling information are sent over the bridge to the native side, where it's used to update the actual native UI components.
React Native Skia: Instead of relying on the traditional bridge to communicate and update native components, Skia operates more directly. The Skia library, running on the native side, takes the instructions from your JavaScript Skia components and renders them directly in its own dedicated rendering thread. This means the actual drawing and painting are done independently of the main UI thread, which can help keep animations smooth and responsive even if there's heavy JavaScript processing happening.
Performance Implications:
Dedicated Rendering Thread: By having a dedicated thread for Skia's rendering, the workload of painting and animation is offloaded from the main UI thread. This can lead to smoother animations and a more responsive UI, especially for complex and graphics-intensive apps.
Reduced Bridge Overhead: Traditional React Native apps can suffer from performance issues related to the bridge, particularly when there's a lot of data being passed back and forth. Since Skia operates more directly and doesn't rely as heavily on the bridge for rendering, it can reduce some of these bottlenecks.