React Native: JavaScript Render Native UI Như Thế Nào

Series: Cross-Platform Mobile Development
Trước đó: Ionic & Capacitor: Web Tech Biến Thành Mobile App
Tiếp theo: Flutter: Dart Vẽ Từng Pixel Như Thế Nào
React Native có approach khác biệt cơ bản so với Ionic. Thay vì chạy app trong WebView, React Native dùng JavaScript để điều khiển native UI component thật. Khi bạn viết <View>, nó trở thành UIView thật trên iOS và android.view.View trên Android.
Không WebView. Không HTML. Không CSS. Native component thật, được orchestrate bởi JavaScript.
Nghe thanh lịch — và đúng là vậy. Nhưng mechanism làm việc này đã trải qua một đợt overhaul kiến trúc lớn. Hiểu cả kiến trúc cũ và mới sẽ cho thấy tại sao React Native từng gặp vấn đề performance và cách nó đã giải quyết triệt để.
Ý Tưởng Cốt Lõi
Trong web app, browser render mọi thứ. Trong React Native, native platform render mọi thứ:
Bạn viết React component, nhưng thay vì web element, bạn dùng React Native primitive:
| React (Web) | React Native | iOS Native | Android Native |
|---|---|---|---|
<div> | <View> | UIView | android.view.View |
<span> | <Text> | UILabel | TextView |
<img> | <Image> | UIImageView | ImageView |
<input> | <TextInput> | UITextField | EditText |
<button> | <Pressable> | UIButton | Button |
<ul> | <FlatList> | UITableView | RecyclerView |
// Trông giống React, nhưng render native component
import { View, Text, Image, Pressable } from 'react-native';
function ProfileCard({ user }) {
return (
<View style={styles.card}>
<Image source={{ uri: user.avatar }} style={styles.avatar} />
<Text style={styles.name}>{user.name}</Text>
<Pressable onPress={() => follow(user.id)}>
<Text>Follow</Text>
</Pressable>
</View>
);
}Code này tạo instance UIView, UIImageView, UILabel, và UIButton thật trên iOS — không phải web element bên trong WebView.
Kiến Trúc Cũ (Trước 2022)
Hiểu kiến trúc cũ giải thích tại sao React Native từng có vấn đề performance và tại sao cần viết lại.
Ba Thread
React Native chạy trên ba thread riêng biệt:
Vấn Đề Bridge
Bridge là bottleneck cốt lõi. Mọi communication giữa JavaScript và native code đều đi qua bridge này:
- JavaScript quyết định tạo
<View>với style nhất định - Instruction được serialize thành JSON và gửi qua bridge
- Shadow thread nhận, tính layout với Yoga (Flexbox engine)
- Layout result được serialize thành JSON và gửi lại qua bridge
- UI thread nhận instruction cuối cùng và tạo native view
Mọi message đều cross bridge dưới dạng serialized JSON. Với UI đơn giản thì OK. Nhưng với interaction phức tạp:
Triệu chứng:
- Scroll giật — touch event phải cross bridge sang JS rồi lại về, thêm latency
- Animation stutter — JS-driven animation gửi hàng trăm message mỗi giây qua bridge
- Startup chậm — toàn bộ React Native runtime phải initialize trước khi UI nào xuất hiện
- Dropped frame — nếu bridge bị nghẽn, frame bị skip
Đây là lý do React Native bị mang tiếng "gần native nhưng chưa đủ" về performance.
New Architecture (2022-Hiện Tại)
New Architecture của React Native là viết lại từ gốc communication layer. Nó loại bỏ hoàn toàn bridge.
Ba Trụ Cột
1. JSI (JavaScript Interface)
Thay đổi lớn nhất. JSI thay bridge bằng direct C++ binding giữa JavaScript và native code.
Thay vì serialize mọi thứ thành JSON và gửi qua asynchronous bridge, JavaScript giờ có thể gọi C++ function trực tiếp — và C++ có thể gọi ngược lại JavaScript trực tiếp.
Kiến trúc cũ:
JS → serialize thành JSON → bridge → deserialize → Native
Native → serialize thành JSON → bridge → deserialize → JS
Kiến trúc mới (JSI):
JS ↔ C++ ↔ Native (direct function call, không serialization)Điều này có nghĩa:
- Không serialization overhead — object được share by reference, không copy
- Synchronous call khi cần — JS có thể gọi native code và nhận result ngay lập tức
- Bất kỳ JS engine — JSI engine-agnostic (hoạt động với Hermes, V8, hoặc JavaScriptCore)
2. Fabric (New Renderer)
Fabric là rendering system mới thay thế UI manager cũ. Cải tiến chính:
Concurrent rendering: Fabric tích hợp với concurrent feature của React 18. UI update có thể được ưu tiên — user tap được priority cao hơn background data refresh.
Synchronous layout: Trong kiến trúc cũ, layout được tính trên thread riêng với async bridge communication. Fabric có thể tính layout synchronously khi cần, loại bỏ "layout flash" (view xuất hiện chớp nhoáng ở vị trí sai).
Shared ownership: Cả JavaScript và native code đều có thể reference cùng một UI node. Trong kiến trúc cũ, chỉ một bên "sở hữu" view tại một thời điểm.
3. TurboModules
TurboModules thay thế Native Modules system cũ. Hai cải tiến chính:
Lazy loading: Native Modules cũ đều initialize lúc startup, kể cả khi không bao giờ dùng. TurboModules chỉ load khi lần đầu access — cải thiện đáng kể startup time.
Type-safe interface: TurboModules dùng CodeGen để generate C++ interface definition từ TypeScript spec. Nghĩa là type error bị bắt lúc build time, không phải runtime.
// TurboModule spec (TypeScript)
import { TurboModule, TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
getConstants(): { apiUrl: string };
fetchUser(id: number): Promise<{ name: string; email: string }>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('UserModule');// Android implementation
public class UserModule extends NativeUserModuleSpec {
@Override
public Map<String, Object> getConstants() {
return Map.of("apiUrl", "https://api.example.com");
}
@Override
public void fetchUser(double id, Promise promise) {
// Native implementation
promise.resolve(/* user data */);
}
}CodeGen generate C++ interface mà cả hai bên phải conform — bắt mismatch lúc compile time thay vì crash lúc runtime.
Hermes: JavaScript Engine Của React Native
React Native ship với Hermes, JavaScript engine build riêng cho mobile:
Tại Sao Không Dùng V8 Hay JavaScriptCore?
V8 (engine của Chrome) và JavaScriptCore (engine của Safari) được thiết kế cho browser. Chúng optimize cho session chạy lâu với JIT compilation. Mobile app có nhu cầu khác:
- Startup nhanh — user kỳ vọng app mở tức thì
- Ít memory — thiết bị mobile có RAM hạn chế
- Performance có thể dự đoán — không JIT warmup gây jank đầu phiên
Cách Hermes Hoạt Động
Hermes đi approach khác: Ahead-of-Time (AOT) compilation thành bytecode.
Thay vì ship JavaScript thô và compile trên device (như V8/JSC), Hermes compile code thành bytecode lúc build time. Trên device, Hermes chỉ execute bytecode đã compile sẵn.
Kết quả:
- Startup nhanh hơn ~50% so với JavaScriptCore
- Ít memory hơn ~30%
- App size nhỏ hơn — bytecode compact hơn JavaScript thô
- Không JIT warmup — performance nhất quán từ frame đầu tiên
Styling: Không Phải CSS, Nhưng Gần Giống
React Native không dùng CSS. Thay vào đó, dùng JavaScript object syntax giống CSS:
import { StyleSheet, View, Text } from 'react-native';
function Card() {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 16,
backgroundColor: '#ffffff',
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3, // Android shadow
},
title: {
fontSize: 18,
fontWeight: 'bold',
color: '#1a1a1a',
},
});Layout dùng Flexbox (qua Yoga engine), nhưng có vài khác biệt so với web CSS:
flexDirectionmặc định là'column'(không phải'row'như web)- Mọi dimension không có đơn vị (không
px,em,rem) - Không cascading — style không inherit (trừ text trong
<Text>) - Không media query (dùng
DimensionsAPI hoặcuseWindowDimensions)
Navigation: React Navigation
React Native không có navigation system built-in. React Navigation là de facto standard:
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}Với @react-navigation/native-stack, navigation animation và gesture được xử lý bởi native navigation controller (UINavigationController trên iOS, Fragment trên Android) — không phải JavaScript-driven animation. Cho cảm giác navigation native thật sự.
Khi Nào React Native Là Lựa Chọn Đúng
Hoàn Hảo ✅
- Team đã biết React — learning curve rất thấp
- Cần native look-and-feel — native component nghĩa là native behavior
- Muốn share logic với React web app — business logic, state management, API layer có thể share
- App phức tạp có UX đặc thù platform — React Native dễ customize cho từng platform
- App có real-time interaction — chat, social feed, collaborative editing
Cân Nhắc ⚠️
- Team không biết React — React paradigm (hook, state, effect) có learning curve
- Cần pixel-perfect custom UI — React Native component trông native, nghĩa là trông khác nhau giữa iOS và Android
- Dùng WebView nhiều — nếu app chủ yếu là web content, Ionic/Capacitor đơn giản hơn
Không Nên ❌
- Game hoặc app đồ họa nặng — dùng Unity, Godot, hoặc Flutter
- App ít cần native API — nếu chỉ cần camera và push notification, Ionic đơn giản hơn
- App sẵn có Angular/Vue — React Native yêu cầu React knowledge
Ecosystem Năm 2026
Ecosystem của React Native khổng lồ và đã battle-tested:
- Expo — cách phổ biến nhất để build React Native app. Managed workflow, EAS Build, OTA update, và SDK phong phú. Nhiều team không bao giờ cần eject.
- React Navigation — native navigation với stack, tab, và drawer navigator
- Reanimated 3 — declarative animation chạy trên UI thread (không cross bridge)
- React Native MMKV — key-value storage cực nhanh
- React Native Skia — Skia rendering engine trong React Native (cho custom drawing)
- Expo Router — file-based routing (giống Next.js cho mobile)
Ai Dùng React Native?
App lớn chạy React Native trong production:
- Meta — Facebook, Instagram, Messenger, Ads Manager
- Microsoft — Xbox app, Office, Teams, Outlook
- Shopify — toàn bộ mobile app
- Discord — iOS và Android
- Bloomberg — mobile financial terminal
- Coinbase — trading cryptocurrency
- Flipkart — e-commerce lớn nhất Ấn Độ
Đây không phải toy app. Chúng là sản phẩm tỷ đô phục vụ hàng trăm triệu user.
Key Takeaway
- React Native render native component thật, không phải web element —
<View>thànhUIView/android.view.View - Kiến trúc bridge cũ (JSON serialization) gây bottleneck performance — scroll giật, animation stutter, startup chậm
- New Architecture (JSI + Fabric + TurboModules) loại bỏ bridge bằng direct C++ binding — cải tiến mang tính cách mạng
- Hermes engine mang đến startup nhanh và ít memory nhờ ahead-of-time bytecode compilation
- Ecosystem trưởng thành — Expo, React Navigation, Reanimated giúp build app phức tạp
- Nếu biết React, bạn đã 70% chặng đường để build React Native app — paradigm chuyển thẳng
New Architecture của React Native là canh bạc rằng model "JavaScript điều khiển native component" có thể hoạt động ở scale lớn. Kết quả — được ship bởi Meta, Microsoft, Shopify, và Discord — chứng minh canh bạc đó đã thắng.
Series: Cross-Platform Mobile Development
Trước đó: Ionic & Capacitor: Web Tech Biến Thành Mobile App
Tiếp theo: Flutter: Dart Vẽ Từng Pixel Như Thế Nào
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.