บทนำ: ยุคใหม่ของ React Native
ถ้าคุณเป็นนักพัฒนา React Native มาสักพัก คุณคงรู้สึกได้ว่าช่วง 2-3 ปีที่ผ่านมานี่คือช่วงเวลาที่เปลี่ยนแปลงเยอะมาก React Native ได้ผ่านการเปลี่ยนแปลงครั้งสำคัญที่สุดในประวัติศาสตร์ของเฟรมเวิร์ก ด้วยการเปิดตัว New Architecture ที่กลายเป็นค่าเริ่มต้นตั้งแต่เวอร์ชัน 0.76 และกลายเป็นสิ่งบังคับใน React Native 0.82
ซึ่งหมายความว่า สถาปัตยกรรมเก่าที่ใช้ Bridge ใช้งานไม่ได้อีกแล้ว ถือเป็นการเปลี่ยนแปลงที่ใหญ่ที่สุดนับตั้งแต่ React Native เปิดตัวครั้งแรกเมื่อ 10 ปีที่แล้วเลย
สำหรับนักพัฒนาที่ใช้ React Native อยู่ในปี 2025-2026 การเข้าใจ New Architecture ไม่ใช่ทางเลือกอีกต่อไป แต่เป็น สิ่งจำเป็น ในบทความนี้ เราจะมาอธิบายทุกองค์ประกอบของ New Architecture กันแบบละเอียด ตั้งแต่ JSI, TurboModules, Fabric ไปจนถึง Codegen พร้อมตัวอย่างโค้ดจริงและแนวทางปฏิบัติที่ดีที่สุดสำหรับการย้ายระบบ
สถาปัตยกรรมเก่า vs สถาปัตยกรรมใหม่
ปัญหาของ Bridge Architecture
ในสถาปัตยกรรมเก่า React Native ใช้ Bridge เป็นตัวกลางในการสื่อสารระหว่าง JavaScript thread กับ Native thread ข้อมูลทุกอย่างที่ส่งผ่าน Bridge จะถูกแปลงเป็น JSON (serialization) แล้วก็แปลงกลับ (deserialization) ซึ่งทำให้เกิดคอขวดด้านประสิทธิภาพอย่างมาก
พูดง่ายๆ ก็คือ มันเหมือนกับการส่งจดหมายไปมาระหว่างสองฝ่าย แทนที่จะคุยกันตรงๆ
- การสื่อสารแบบ Asynchronous เท่านั้น: JavaScript และ Native ไม่สามารถเรียกใช้งานกันได้โดยตรง ต้องส่งข้อมูลผ่าน Bridge เสมอ
- JSON Serialization: ข้อมูลทุกชิ้นต้องถูกแปลงเป็น JSON ก่อนส่ง ทำให้สิ้นเปลืองทรัพยากร CPU และหน่วยความจำ
- การโหลด Native Modules ทั้งหมดตอนเริ่มต้น: ทุก Native Module จะถูกโหลดเข้ามาตอนแอปเริ่มทำงาน แม้ว่าจะยังไม่ได้ใช้จริงเลยด้วยซ้ำ
- ปัญหา Race Condition: เนื่องจากการสื่อสารเป็นแบบ Asynchronous จึงอาจเกิดปัญหาลำดับการทำงานที่ไม่ถูกต้อง
องค์ประกอบหลักของ New Architecture
New Architecture ประกอบด้วย 4 องค์ประกอบหลักที่ทำงานร่วมกัน:
- JSI (JavaScript Interface) — อินเทอร์เฟซ C++ ที่เข้ามาแทนที่ Bridge
- TurboModules — ระบบ Native Module แบบใหม่ที่โหลดแบบ Lazy Loading
- Fabric — ระบบ Renderer ใหม่ที่รองรับ Concurrent Rendering
- Codegen — เครื่องมือสร้างโค้ดอัตโนมัติจาก TypeScript/Flow definitions
มาดูรายละเอียดของแต่ละส่วนกันเลย
JSI (JavaScript Interface): หัวใจของสถาปัตยกรรมใหม่
JSI คือ อินเทอร์เฟซ C++ ที่เป็นรากฐานของ New Architecture ทั้งหมด แทนที่จะส่งข้อมูลผ่าน Bridge แบบ JSON อย่างเดิม JSI ช่วยให้ JavaScript engine สามารถอ้างอิง (hold references) ไปยัง Native objects ได้โดยตรง
ผลก็คือ JavaScript สามารถเรียกใช้ฟังก์ชัน Native ได้เลยโดยไม่ต้องผ่านการ serialize/deserialize ข้อมูล ซึ่งเร็วกว่าเดิมมากๆ
การทำงานของ JSI
JSI ทำหน้าที่เป็นชั้นนามธรรม (abstraction layer) ที่อยู่ระหว่าง JavaScript engine กับ Native code โดยมีคุณสมบัติสำคัญหลายอย่าง:
- Synchronous calls: รองรับการเรียกใช้ฟังก์ชันแบบ Synchronous ได้ ไม่ต้องรอ async callback อีกต่อไป
- Direct memory sharing: JavaScript แชร์หน่วยความจำกับ Native ได้โดยตรง ลดการคัดลอกข้อมูลที่ไม่จำเป็น
- Engine agnostic: JSI ไม่ผูกติดกับ JavaScript engine ใดๆ โดยเฉพาะ จึงเปลี่ยน engine ได้ง่าย (เช่น จาก JSC เป็น Hermes)
มาดูตัวอย่างการใช้งาน JSI ในการสร้าง Host Object กัน:
// ตัวอย่าง C++ Host Object สำหรับ JSI
#include <jsi/jsi.h>
using namespace facebook::jsi;
class MyNativeModule : public HostObject {
public:
Value get(Runtime& runtime, const PropNameID& name) override {
auto methodName = name.utf8(runtime);
if (methodName == "multiply") {
return Function::createFromHostFunction(
runtime,
PropNameID::forAscii(runtime, "multiply"),
2,
[](Runtime& runtime,
const Value& thisValue,
const Value* arguments,
size_t count) -> Value {
double a = arguments[0].asNumber();
double b = arguments[1].asNumber();
return Value(a * b);
}
);
}
return Value::undefined();
}
};
ในตัวอย่างนี้ เราสร้าง Host Object ที่มีเมธอด multiply ซึ่ง JavaScript เรียกใช้ได้โดยตรงผ่าน JSI ไม่ต้องผ่าน Bridge เลย สังเกตว่าทุกอย่างเป็น C++ ล้วนๆ ทำให้ทำงานได้เร็วมาก
TurboModules: Native Modules ยุคใหม่
TurboModules คือวิวัฒนาการของ Native Modules ที่ออกแบบมาให้ทำงานบน JSI โดยจุดเด่นที่สุดคือ Lazy Loading ซึ่งหมายความว่า Module จะถูกโหลดเฉพาะเมื่อถูกเรียกใช้งานจริงเท่านั้น ไม่ได้โหลดมาทั้งหมดตอนเริ่มแอปเหมือนเดิม
จากประสบการณ์จริง แค่เปลี่ยนมาใช้ TurboModules ก็ช่วยให้เวลาเปิดแอปลดลงอย่างเห็นได้ชัดแล้ว
ข้อดีของ TurboModules
- ลดเวลาเริ่มต้นแอป: Module ที่ไม่ได้ใช้จะไม่ถูกโหลด ทำให้แอปเริ่มทำงานเร็วขึ้น
- Type Safety: ใช้ Codegen สร้าง interface จาก TypeScript/Flow spec ทำให้ตรวจสอบ type ได้แม่นยำ
- Synchronous access: รองรับการเรียกใช้แบบ Synchronous ผ่าน JSI
- ลดการใช้หน่วยความจำ: โหลดเฉพาะ Module ที่จำเป็น ลดการใช้ RAM ได้อย่างมีนัยสำคัญ
การสร้าง TurboModule
เริ่มจากการกำหนด spec ด้วย TypeScript ก่อน:
// NativeCalculator.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
add(a: number, b: number): number;
subtract(a: number, b: number): number;
multiply(a: number, b: number): Promise<number>;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'NativeCalculator'
);
จากนั้นสร้าง Native implementation สำหรับ Android ด้วย Kotlin:
// NativeCalculatorModule.kt
package com.myapp.calculator
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModule
@ReactModule(name = NativeCalculatorModule.NAME)
class NativeCalculatorModule(
reactContext: ReactApplicationContext
) : NativeCalculatorSpec(reactContext) {
override fun getName(): String = NAME
override fun add(a: Double, b: Double): Double {
return a + b
}
override fun subtract(a: Double, b: Double): Double {
return a - b
}
override fun multiply(a: Double, b: Double, promise: Promise) {
promise.resolve(a * b)
}
companion object {
const val NAME = "NativeCalculator"
}
}
และสำหรับ iOS ด้วย Swift ใน React Native 0.79+:
// NativeCalculatorModule.swift
import Foundation
import React
import ReactCommon
@objc(NativeCalculatorModule)
class NativeCalculatorModule: NSObject, NativeCalculatorSpec {
@objc static func moduleName() -> String! {
return "NativeCalculator"
}
func add(_ a: Double, b: Double) -> NSNumber {
return NSNumber(value: a + b)
}
func subtract(_ a: Double, b: Double) -> NSNumber {
return NSNumber(value: a - b)
}
func multiply(
_ a: Double,
b: Double,
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock
) {
resolve(NSNumber(value: a * b))
}
}
จะเห็นว่าโครงสร้างค่อนข้างตรงไปตรงมา ส่วนที่ยุ่งยากหน่อยคือการ setup โปรเจกต์ให้ถูก แต่ตัว implementation จริงๆ ไม่ได้ซับซ้อนเท่าไร
Fabric: ระบบ Renderer ใหม่
Fabric คือระบบ Rendering ใหม่ที่เข้ามาแทนที่ UI Manager เดิม ถูกออกแบบมาให้ทำงานร่วมกับ JSI และรองรับ Concurrent Rendering จาก React 18+/19
ความแตกต่างจาก UI Manager เดิม
ใน UI Manager เดิม การ render จะทำงานบน thread แยกต่างหากจาก JavaScript thread และการสื่อสารผ่าน Bridge ทำให้เกิด latency ที่เห็นได้ชัด โดยเฉพาะในแอนิเมชันที่ซับซ้อน (ใครเคยเจอปัญหาแอนิเมชันกระตุกบ้างครับ? นั่นแหละ)
Fabric แก้ปัญหาเหล่านี้ได้หลายจุด:
- การ render บน thread ใดก็ได้: Fabric ไม่ถูกจำกัดให้ทำงานบน thread เดียว กระจายงานได้อย่างมีประสิทธิภาพมากขึ้น
- Synchronous layout: การคำนวณ layout ทำได้แบบ Synchronous ผ่าน JSI ลด latency ในการอัปเดต UI
- Concurrent rendering: รองรับ React 19 Concurrent features อย่าง Suspense, Transitions และ useTransition
- Immutable Shadow Tree: ใช้ Shadow Tree แบบ Immutable ที่แชร์ระหว่าง thread ได้อย่างปลอดภัย
การใช้ Fabric Component
มาดูตัวอย่างการสร้าง Fabric Native Component กัน:
// MyCustomViewNativeComponent.ts
import type { ViewProps } from 'react-native';
import type {
Float,
Int32,
WithDefault,
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
interface NativeProps extends ViewProps {
borderRadius?: WithDefault<Float, 0>;
borderColor?: string;
maxCount?: WithDefault<Int32, 10>;
label?: string;
}
export default codegenNativeComponent<NativeProps>(
'MyCustomView'
);
แล้วก็ใช้งาน Component ใน React ได้ปกติเลย:
import React from 'react';
import { View, StyleSheet } from 'react-native';
import MyCustomView from './MyCustomViewNativeComponent';
const App = () => {
return (
<View style={styles.container}>
<MyCustomView
style={styles.customView}
borderRadius={12}
borderColor="#3498db"
maxCount={5}
label="สวัสดี React Native"
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
customView: {
width: 200,
height: 200,
},
});
export default App;
Codegen: สร้างโค้ดอัตโนมัติ
Codegen เป็นเครื่องมือที่อาจจะไม่ค่อยเป็นที่พูดถึง แต่จริงๆ แล้วสำคัญมาก มันสร้างโค้ด C++ และ Java/Kotlin/Objective-C bindings โดยอัตโนมัติจาก TypeScript หรือ Flow definitions ของ TurboModules และ Fabric Components
ข้อดีที่ชัดเจนคือ:
- ลดโค้ด boilerplate: ไม่ต้องเขียนโค้ดเชื่อมต่อ (binding code) ด้วยตัวเอง
- Type safety: รับประกันความถูกต้องของ type ระหว่าง JavaScript กับ Native
- ลดข้อผิดพลาด: ป้องกัน type mismatch ที่เคยเป็นปัญหาบ่อยๆ ในสถาปัตยกรรมเก่า
การกำหนดค่า Codegen ใน package.json ก็ทำได้ง่ายๆ แบบนี้:
{
"name": "my-native-library",
"version": "1.0.0",
"codegenConfig": {
"name": "MyLibrarySpecs",
"type": "all",
"jsSrcsDir": "src",
"android": {
"javaPackageName": "com.myapp.library"
}
}
}
Hermes: JavaScript Engine ที่ออกแบบมาเพื่อ React Native โดยเฉพาะ
Hermes เป็น JavaScript engine แบบ open-source ที่สร้างมาเฉพาะสำหรับ React Native ตั้งแต่ React Native 0.70+ Hermes กลายเป็น engine เริ่มต้น และใน React Native 0.79 JSC (JavaScriptCore) ถูกนำออกจาก core อย่างเป็นทางการแล้ว
ข้อดีของ Hermes
- เวลาเริ่มต้นเร็วขึ้น 20-40%: Hermes คอมไพล์ JavaScript เป็น bytecode ล่วงหน้า (AOT compilation) ไม่ต้องแปลง JavaScript ตอนรันไทม์
- ใช้หน่วยความจำน้อยลง 20-30%: Garbage collector ปรับแต่งมาสำหรับอุปกรณ์มือถือโดยเฉพาะ
- ขนาดแอปเล็กลง: Bytecode มีขนาดเล็กกว่า JavaScript source code อยู่พอสมควร
- รองรับ JSI อย่างเต็มที่: ทำงานร่วมกับ New Architecture ได้อย่างราบรื่น
ตรวจสอบว่าแอปใช้ Hermes หรือไม่
วิธีเช็คง่ายๆ:
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const HermesCheck = () => {
const isHermes = () => {
return typeof HermesInternal !== 'undefined';
};
return (
<View style={styles.container}>
<Text style={styles.text}>
{isHermes()
? 'กำลังใช้ Hermes Engine'
: 'ไม่ได้ใช้ Hermes Engine'}
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 20,
alignItems: 'center',
},
text: {
fontSize: 18,
fontWeight: 'bold',
},
});
export default HermesCheck;
การย้ายระบบไปสู่ New Architecture
เอาจริงๆ ส่วนนี้คือสิ่งที่นักพัฒนาหลายคนกังวลมากที่สุด แต่ข่าวดีคือถ้าคุณใช้ Expo อยู่ กระบวนการย้ายระบบจะง่ายกว่ามาก เพราะ Expo จัดการ configuration ส่วนใหญ่ให้อัตโนมัติ สำหรับ Expo SDK 53+ New Architecture เปิดใช้งานโดยค่าเริ่มต้นเลย
การเปิดใช้ New Architecture ใน Expo
// app.json
{
"expo": {
"name": "MyApp",
"slug": "my-app",
"version": "1.0.0",
"newArchEnabled": true,
"plugins": [
"expo-router"
]
}
}
การเปิดใช้สำหรับ Bare React Native (Android)
ใน android/gradle.properties แค่เพิ่มบรรทัดเดียว:
# เปิดใช้ New Architecture
newArchEnabled=true
การเปิดใช้สำหรับ Bare React Native (iOS)
# ติดตั้ง pods ด้วย New Architecture flag
cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
ขั้นตอนการย้ายระบบแบบปลอดภัย
ขั้นตอนที่แนะนำมีดังนี้:
- ตรวจสอบ dependencies: ดูว่า third-party libraries ที่ใช้อยู่รองรับ New Architecture หรือยัง เช็คได้ที่
reactnative.directory - อัปเดต React Native: อัปเกรดเป็นเวอร์ชันล่าสุด (0.79+) ที่รองรับ New Architecture อย่างเต็มที่
- เปิดใช้ New Architecture: ตั้งค่า flag ตามที่แสดงด้านบน
- ทดสอบอย่างละเอียด: ทดสอบทุกฟีเจอร์ เพราะบาง library อาจมีปัญหากับ New Architecture ได้
- แก้ไข Native Modules: ย้าย Native Modules ที่สร้างเองไปเป็น TurboModules
เครื่องมือช่วยตรวจสอบ
# ใช้ CLI doctor เพื่อตรวจสอบ
npx @react-native-community/cli doctor
# ตรวจสอบ dependencies ที่เข้ากันได้
npx react-native info
ประสิทธิภาพที่ดีขึ้นจริงๆ
ตัวเลขไม่โกหก จากการทดสอบ benchmark ในปี 2025-2026 ผลลัพธ์ค่อนข้างน่าประทับใจ:
- Frame rate: คงที่ที่ 60 fps ในกรณีส่วนใหญ่ ลดการ drop frame ไปได้เยอะ
- เวลาเริ่มต้นแอป: ลดลงถึง 40% เทียบกับสถาปัตยกรรมเก่า
- การใช้หน่วยความจำ: ลดลง 20-30% ด้วย Hermes และ TurboModules
- Android cold start: เร็วขึ้น 12% (ประมาณ 400ms) จากการใช้ uncompressed JS bundles ใน React Native 0.79
เทคนิคการเพิ่มประสิทธิภาพเพิ่มเติม
นอกจากการใช้ New Architecture แล้ว ยังมีเทคนิคอื่นๆ ที่ช่วยเพิ่มประสิทธิภาพให้แอปได้อีก มาดูกัน
1. การ optimize FlatList
FlatList เป็นหนึ่งใน component ที่มีปัญหาเรื่อง performance บ่อยที่สุด นี่คือการตั้งค่าที่ผมแนะนำ:
import React, { useCallback, useMemo } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
interface Item {
id: string;
title: string;
description: string;
}
const ITEM_HEIGHT = 80;
const OptimizedList = ({ data }: { data: Item[] }) => {
const renderItem = useCallback(({ item }: { item: Item }) => (
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.description}>{item.description}</Text>
</View>
), []);
const getItemLayout = useCallback(
(_: any, index: number) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
}),
[]
);
const keyExtractor = useCallback(
(item: Item) => item.id,
[]
);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
getItemLayout={getItemLayout}
windowSize={5}
maxToRenderPerBatch={10}
initialNumToRender={10}
removeClippedSubviews={true}
updateCellsBatchingPeriod={50}
/>
);
};
const styles = StyleSheet.create({
item: {
height: ITEM_HEIGHT,
padding: 16,
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
title: {
fontSize: 16,
fontWeight: 'bold',
},
description: {
fontSize: 14,
color: '#666',
marginTop: 4,
},
});
2. การใช้ React.memo อย่างมีประสิทธิภาพ
React.memo ยังคงมีประโยชน์มากในหลายๆ กรณี แม้ว่าจะมี React Compiler แล้วก็ตาม:
import React, { memo, useCallback, useState } from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
} from 'react-native';
interface CardProps {
title: string;
subtitle: string;
onPress: (id: string) => void;
id: string;
}
const Card = memo<CardProps>(({ title, subtitle, onPress, id }) => {
const handlePress = useCallback(() => {
onPress(id);
}, [onPress, id]);
return (
<TouchableOpacity
style={styles.card}
onPress={handlePress}
>
<Text style={styles.cardTitle}>{title}</Text>
<Text style={styles.cardSubtitle}>{subtitle}</Text>
</TouchableOpacity>
);
});
const CardList = () => {
const [selectedId, setSelectedId] = useState<string | null>(null);
const handleCardPress = useCallback((id: string) => {
setSelectedId(id);
}, []);
return (
<View>
<Card
id="1"
title="React Native"
subtitle="สถาปัตยกรรมใหม่"
onPress={handleCardPress}
/>
<Card
id="2"
title="Hermes Engine"
subtitle="ประสิทธิภาพที่เหนือชั้น"
onPress={handleCardPress}
/>
</View>
);
};
const styles = StyleSheet.create({
card: {
padding: 16,
margin: 8,
borderRadius: 12,
backgroundColor: '#fff',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
},
cardSubtitle: {
fontSize: 14,
color: '#888',
marginTop: 4,
},
});
3. การใช้ Animation บน Native Thread
สำหรับแอนิเมชัน แนะนำให้ใช้ react-native-reanimated เพราะรันบน native thread โดยตรง ทำให้ได้ 60 fps แม้ JS thread จะ busy อยู่:
import React from 'react';
import { View, StyleSheet } from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
withTiming,
Easing,
} from 'react-native-reanimated';
import {
Gesture,
GestureDetector,
GestureHandlerRootView,
} from 'react-native-gesture-handler';
const AnimatedCard = () => {
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const scale = useSharedValue(1);
const panGesture = Gesture.Pan()
.onUpdate((event) => {
translateX.value = event.translationX;
translateY.value = event.translationY;
})
.onEnd(() => {
translateX.value = withSpring(0);
translateY.value = withSpring(0);
});
const tapGesture = Gesture.Tap()
.onStart(() => {
scale.value = withTiming(0.95, {
duration: 100,
easing: Easing.inOut(Easing.ease),
});
})
.onEnd(() => {
scale.value = withSpring(1);
});
const composedGesture = Gesture.Simultaneous(
panGesture,
tapGesture
);
const animatedStyle = useAnimatedStyle(() => ({
transform: [
{ translateX: translateX.value },
{ translateY: translateY.value },
{ scale: scale.value },
],
}));
return (
<GestureHandlerRootView style={styles.container}>
<GestureDetector gesture={composedGesture}>
<Animated.View style={[styles.box, animatedStyle]}>
</Animated.View>
</GestureDetector>
</GestureHandlerRootView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
box: {
width: 200,
height: 200,
borderRadius: 16,
backgroundColor: '#3498db',
},
});
React 19 และ React Compiler ใน React Native
React Native 0.78+ นำ React 19 มาใช้อย่างเป็นทางการ ซึ่งมาพร้อมกับ React Compiler ที่ถือว่าเป็น game changer เลยก็ว่าได้ React Compiler จะวิเคราะห์โค้ดของคุณและเพิ่ม memoization ให้อัตโนมัติ ลดความจำเป็นในการใช้ useMemo, useCallback และ React.memo ด้วยตัวเอง
การเปิดใช้ React Compiler
// babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
[
'babel-plugin-react-compiler',
{
target: '19',
},
],
],
};
สำหรับ Expo ก็แค่เปิดใน app.json:
// app.json
{
"expo": {
"experiments": {
"reactCompiler": true
}
}
}
ด้วย React Compiler โค้ดจะเปลี่ยนจากแบบนี้:
// ก่อน: ต้อง memoize ด้วยตนเอง
const ExpensiveComponent = ({ items }) => {
const sortedItems = useMemo(
() => items.sort((a, b) => a.name.localeCompare(b.name)),
[items]
);
const handlePress = useCallback((id) => {
console.log('Pressed:', id);
}, []);
return <ItemList items={sortedItems} onPress={handlePress} />;
};
// หลัง: React Compiler จัดการ memoization ให้อัตโนมัติ
const ExpensiveComponent = ({ items }) => {
const sortedItems = items.sort(
(a, b) => a.name.localeCompare(b.name)
);
const handlePress = (id) => {
console.log('Pressed:', id);
};
return <ItemList items={sortedItems} onPress={handlePress} />;
};
เขียนโค้ดได้เรียบง่ายขึ้นมาก โดยที่ performance ไม่ตก สะดวกมากจริงๆ
Expo SDK 53-55: ตัวเร่งการพัฒนา
Expo ยังคงเป็นเครื่องมือสำคัญที่ทำให้การพัฒนา React Native ง่ายขึ้นเยอะ ในปี 2025-2026 มีการอัปเดตหลายอย่างที่น่าสนใจ:
Expo SDK 53
- รองรับ React Native 0.79 และ React 19
- New Architecture เปิดใช้งานโดยค่าเริ่มต้น
- Edge-to-edge layout สำหรับ Android เป็นค่าเริ่มต้น
- Hot reloading สำหรับ environment variables (อันนี้ดีมาก ไม่ต้อง restart อีกแล้ว)
- แทนที่
expo-avด้วยexpo-audioและexpo-video - แทนที่
expo-background-fetchด้วยexpo-background-task
Expo SDK 54-55
- React Native 0.82-0.83 ที่บังคับใช้ New Architecture
- ไม่สามารถปิด New Architecture ได้อีกต่อไป
- สถิติการใช้งาน New Architecture สูงถึง 83% ของโปรเจกต์ SDK 54
React Server Components บน Mobile
หนึ่งในนวัตกรรมที่น่าตื่นเต้นที่สุดในตอนนี้คือการนำ React Server Components (RSC) มาใช้บนแอปมือถือผ่าน Expo Router ซึ่งช่วยให้:
- ลดขนาด JavaScript bundle บนอุปกรณ์ลงได้
- ย้ายการ fetch ข้อมูลไปทำบน server
- Streaming UI จาก server ไปยัง client
- Bundle splitting อัตโนมัติ
// app/posts/[id].tsx - Server Component
import { Text, View } from 'react-native';
export default async function PostScreen({
params,
}: {
params: { id: string };
}) {
const post = await fetch(
`https://api.example.com/posts/${params.id}`
).then((res) => res.json());
return (
<View>
<Text>{post.title}</Text>
<Text>{post.content}</Text>
</View>
);
}
ถ้าคุณเคยใช้ Next.js มาก่อน จะเห็นว่ารูปแบบคล้ายๆ กัน แต่ตอนนี้ทำบน mobile ได้แล้ว
Metro Bundler: เร็วขึ้น 3 เท่า
อีกเรื่องที่อาจจะไม่ได้เป็นข่าวใหญ่เท่าไร แต่ส่งผลต่อชีวิตการทำงานประจำวันมาก Metro bundler ใน React Native 0.79 ได้อัปเกรดเป็นเวอร์ชัน 0.82 ซึ่งเร็วขึ้นอย่างเห็นได้ชัด:
- เวลาเริ่มต้นเร็วขึ้นถึง 3 เท่า ด้วย deferred hashing
- รองรับ
exportsและimportsfields ในpackage.jsonเป็นค่าเริ่มต้น - เหมาะสำหรับโปรเจกต์ขนาดใหญ่และ monorepos
// metro.config.js - การตั้งค่าที่แนะนำ
const { getDefaultConfig, mergeConfig } = require(
'@react-native/metro-config'
);
const defaultConfig = getDefaultConfig(__dirname);
const config = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: true,
inlineRequires: true,
},
}),
},
resolver: {
unstable_enablePackageExports: true,
},
};
module.exports = mergeConfig(defaultConfig, config);
แนวทาง React Native 1.0 และอนาคต
หลังจาก 10 ปีของการพัฒนา React Native กำลังมุ่งหน้าสู่ เวอร์ชัน 1.0 ทีมพัฒนาได้ประกาศที่ React Conf 2025 ว่า 1.0 อยู่ "ใกล้แล้ว" โดยมีเป้าหมายที่ชัดเจน:
- Stable JavaScript API: API ที่เสถียรและไม่เปลี่ยนแปลงบ่อย
- Web alignment: เชื่อมต่อกับมาตรฐาน web มากขึ้น
- Leaner core: แยกส่วนที่ไม่จำเป็นออกจาก core
- Frequent releases: อัปเดตบ่อยขึ้นแต่มีขนาดเล็กลง
สำหรับนักพัฒนาที่ต้องการเตรียมตัวให้พร้อม สิ่งที่ควรทำตอนนี้คือ:
- ใช้ New Architecture ตั้งแต่วันนี้ อย่ารอ
- ย้ายไปใช้ Hermes เป็น JavaScript engine หลัก
- อัปเดต React Native และ Expo SDK ให้ทันสมัยอยู่เสมอ
- เริ่มเรียนรู้ React Server Components สำหรับ mobile
- ใช้ TypeScript สำหรับ TurboModules และ Fabric Components เพื่อใช้ประโยชน์จาก Codegen ได้เต็มที่
สรุป
React Native New Architecture คือการเปลี่ยนแปลงครั้งใหญ่ที่สุดในประวัติศาสตร์ของเฟรมเวิร์กนี้ และถ้าพูดตรงๆ ก็ต้องบอกว่าเป็นการเปลี่ยนแปลงไปในทิศทางที่ดีขึ้นอย่างชัดเจน
การเข้าใจ JSI, TurboModules, Fabric และ Codegen ไม่ใช่ทางเลือกอีกต่อไป แต่เป็นสิ่งจำเป็นสำหรับทุกนักพัฒนา React Native ในปี 2025-2026 ด้วยเวลาเริ่มต้นที่เร็วขึ้น 40% หน่วยความจำที่ลดลง 20-30% และ frame rate ที่คงที่ 60 fps สถาปัตยกรรมใหม่นี้ทำให้ React Native แข่งขันกับแอป Native ได้อย่างแท้จริง
ไม่ว่าคุณจะเป็นนักพัฒนาที่เพิ่งเริ่มต้นหรือมีประสบการณ์มายาวนาน การเรียนรู้และปรับตัวเข้ากับ New Architecture จะช่วยให้คุณสร้างแอปมือถือที่มีประสิทธิภาพสูงและพร้อมสำหรับอนาคตของ React Native 1.0 ครับ