React Native 0.84์ Hermes V1: ์ฑ๋ฅ ์ต์ ํ, ํ๋ฆฌ์ปดํ์ผ ๋ฐ์ดํธ์ฝ๋, ๊ธฐ์ ๋ฉด์ ๊ฐ์ด๋
Hermes V1์ด React Native 0.84์ ๊ธฐ๋ณธ JavaScript ์์ง์ผ๋ก ์ฑํ๋์ด ๋ฐ์ดํธ์ฝ๋ ํ๋ฆฌ์ปดํ์ผ, Hades ๊ฐ๋น์ง ์ปฌ๋ ํฐ, ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ๋ฅผ ํตํด ํ๊ธฐ์ ์ธ ์ฑ๋ฅ ํฅ์์ ์ ๊ณตํฉ๋๋ค. ๊ธฐ์ ๋ฉด์ ์์ ์์ฃผ ์ถ์ ๋๋ Hermes ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์์ธํ ๋ค๋ฃน๋๋ค.

2026๋ 2์์ ์ถ์๋ React Native 0.84์์ Hermes V1์ด ๊ธฐ๋ณธ JavaScript ์์ง์ผ๋ก ์ฑํ๋์์ต๋๋ค. ์ด๋ React Native ์ญ์ฌ์ ๊ฐ์ฅ ์ค์ํ ์ฑ๋ฅ ๊ฐ์ ์ผ๋ก, ๋น๋ ํ์ ๋ฐ์ดํธ์ฝ๋ ์ปดํ์ผ, Hades ๋์์ฑ ๊ฐ๋น์ง ์ปฌ๋ ํฐ, ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ ์ ๋ต์ ํตํด ๋ชจ๋ฐ์ผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์๋์ ์คํ ํจ์จ์ฑ์ ํฌ๊ฒ ํฅ์์ํต๋๋ค.
Hermes V1์ ๋น๋ ํ์ ๋ฐ์ดํธ์ฝ๋ ์ปดํ์ผ์ ํตํด Time to Interactive(TTI)๋ฅผ 25~50% ๋จ์ถํฉ๋๋ค. ๋ฐํ์ JavaScript ํ์ฑ์ ์ ๊ฑฐํ๊ณ , JavaScriptCore ๋๋น ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ 10~30% ๊ฐ์์ํต๋๋ค.
๋ฐ์ดํธ์ฝ๋ ํ๋ฆฌ์ปดํ์ผ๋ก ์์ ์ค๋ฒํค๋ ์ ๊ฑฐํ๊ธฐ
JavaScriptCore(JSC)๋ V8๊ณผ ๊ฐ์ ๊ธฐ์กด JavaScript ์์ง์ ๋ค๋จ๊ณ ์คํ ํ์ดํ๋ผ์ธ์ ๋ฐ๋ฆ ๋๋ค. ์์ค ์ฝ๋๋ฅผ ํ์ฑํ๊ณ , ์ถ์ ๊ตฌ๋ฌธ ํธ๋ฆฌ(AST)๋ฅผ ์์ฑํ๊ณ , ๋ฐ์ดํธ์ฝ๋๋ก ์ปดํ์ผํ ๋ค์, ๋ฐํ์์ ํซ ๊ฒฝ๋ก๋ฅผ ์ต์ ํํฉ๋๋ค. Hermes๋ ์ด ์ ๊ทผ ๋ฐฉ์์ ๊ทผ๋ณธ์ ์ผ๋ก ๋ณ๊ฒฝํ์ฌ ์ปดํ์ผ์ ๋น๋ ํ์์ผ๋ก ์ด๋์์ผฐ์ต๋๋ค.
React Native ๋น๋ ํ๋ก์ธ์ค์์ Metro ๋ฒ๋ค๋ฌ๊ฐ JavaScript ๋ฒ๋ค์ ์์ฑํฉ๋๋ค. ๊ทธ ํ Hermes ์ปดํ์ผ๋ฌ(hermesc)๊ฐ ์ด ๋ฒ๋ค์ ์ต์ ํ๋ ๋ฐ์ดํธ์ฝ๋๋ก ๋ณํํ์ฌ .hbc ํ์ผ๋ก ์ ์ฅํฉ๋๋ค. ๋ฐํ์์๋ ์์ง์ด ํ๋ฆฌ์ปดํ์ผ๋ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์ง์ ๋ก๋ํ๋ฏ๋ก ํ์ฑ, AST ์์ฑ, JIT ์์
์ง์ฐ์ด ๋ฐ์ํ์ง ์์ต๋๋ค.
const { getDefaultConfig } = require('@react-native/metro-config');
const config = getDefaultConfig(__dirname);
// Hermes bytecode compilation is automatic in 0.84+
// The transformer handles .hbc generation during build
module.exports = {
...config,
transformer: {
...config.transformer,
// hermesParser is now the default
hermesParser: true,
// Inline requires reduce initial bundle evaluation time
inlineRequires: true,
},
};.hbc ํ์ผ์ mmap()์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค ์ฃผ์ ๊ณต๊ฐ์ ์ง์ ๋ฉ๋ชจ๋ฆฌ ๋งคํ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฉ๋ชจ๋ฆฌ ์๋ฐ ์ํฉ์์ ์ด์ ์ฒด์ ๊ฐ ์ฌ์ฉํ์ง ์๋ ๋ฐ์ดํธ์ฝ๋ ์ธ๊ทธ๋จผํธ๋ฅผ ํ์ด์ง ์์ํ ์ ์์ผ๋ฉฐ, Hermes๊ฐ JavaScript ์์ค๋ฅผ ๋ค์ ํ์ฑํ ํ์๊ฐ ์์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ํ๋ ๊ธฐ๊ธฐ์์๋ ํฐ ๋ฒ๋ค์ ์ฌ์ฉํ๋ JSC์์ ๋ฐ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ํฌ๋์๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
Hades: ๋์์ฑ ๊ฐ๋น์ง ์ปฌ๋ ํฐ ์ํคํ ์ฒ
Hermes V1์ ์ฑ๊ธ ์ค๋ ๋ GenGC๋ฅผ ๋์ฒดํ๋ ๋๋ถ๋ถ ๋์์ฑ์ผ๋ก ๋์ํ๋ ์ธ๋๋ณ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ธ Hades๋ฅผ ์ฌ์ฉํฉ๋๋ค. Hades ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๋๋ฒ๊น ๊ณผ ์๋์ด ๋ ๋ฒจ ๊ธฐ์ ๋ฉด์ ์ง๋ฌธ์ ๋ต๋ณํ๋ ๋ฐ ํ์์ ์ ๋๋ค.
GenGC๋ ๋ชจ๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ์์ ์ ๋ฉ์ธ ์ค๋ ๋์์ ์ํํ๊ธฐ ๋๋ฌธ์ ๋์ ๋๋ UI ๋ฒ๋ฒ ๊ฑฐ๋ฆผ์ ์ ๋ฐํ์ต๋๋ค. Facebook for Android์ ๊ฐ์ ๋ณต์กํ ์ฑ์์ GenGC ์ผ์ ์ ์ง๋ ํ๊ท 200ms์์ผ๋ฉฐ, p99 ์ง์ฐ ์๊ฐ์ 1.4์ด์ ๋ฌํ๊ณ , ์ ์ฌ์ ๊ธฐ๊ธฐ์์๋ 7์ด๊น์ง ์น์๊ธฐ๋ ํ์ต๋๋ค.
Hades๋ ์ปฌ๋ ์ ์์ ์ ๋๋ถ๋ถ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ JavaScript ์คํ๊ณผ ๋์์ ์ํํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ์ปฌ๋ ํฐ๋ ์ฌ๋ ์ ๋๋ ์ด์ ์ ๋ํด ์ค๋ ์ท ์ณ ๋ ๋น๊ธฐ๋(snapshot-at-the-beginning) ๋งํฌ ์ค์ ์ ๋ต์ ์ฌ์ฉํ๊ณ , ์ ์ ๋๋ ์ด์ ์ ๋ํด์๋ ์ธ๋ฏธ์คํ์ด์ค ๋ณต์ฌ ์ ๋ต์ ์ ์งํฉ๋๋ค.
// Understanding allocation patterns that work well with Hades
// Short-lived objects in the young generation are collected quickly
function renderProductList(products) {
// Temporary array - young generation, fast collection
const mapped = products.map(product => ({
id: product.id,
display: `${product.name} - $${product.price}`,
}));
return mapped;
}
// Avoid patterns that defeat generational GC
// Don't cache large objects unnecessarily - they promote to old gen
const expensiveCache = {}; // Old generation - less frequent collection
// Instead, use bounded caches with explicit eviction
class BoundedCache {
constructor(maxSize = 100) {
this.maxSize = maxSize;
this.cache = new Map();
}
set(key, value) {
if (this.cache.size >= this.maxSize) {
// Evict oldest entry - allows GC to reclaim memory
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(key, value);
}
get(key) {
return this.cache.get(key);
}
}React Native๋ ํ๋ฆฌํ ๋ด์ด๋ง(pre-tenuring)์ด ์ ์ฉ๋ Hermes๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ์ฒซ 32MiB์ ํ ๋น์ ์ ์ ๋๋ ์ด์ ์ปฌ๋ ์ ์ ๊ฑด๋๋ฐ๊ณ ์ฌ๋ ์ ๋๋ ์ด์ ์ ์ง์ ๋ฐฐ์น๋ฉ๋๋ค. ์ฑ ์ด๊ธฐํ ์ค์ ํ ๋น๋๋ ๊ฐ์ฒด(๋ด๋น๊ฒ์ด์ ์คํ, ๊ธ๋ก๋ฒ ์ํ, API ํด๋ผ์ด์ธํธ)๋ ์ผ๋ฐ์ ์ผ๋ก ์ค๋ ์ด์๋จ์ผ๋ฉฐ, ์ ์ ๊ฐ์ฒด๊ฐ ๋นจ๋ฆฌ ์ฃฝ๋๋ค๋ ์ธ๋ ๊ฐ์ค์ ๋ฐ๋ฅด์ง ์์ต๋๋ค. ํ๋ฆฌํ ๋ด์ด๋ง์ ์์ ์ ๋ถํ์ํ ์ ์ ๋๋ ์ด์ ์ปฌ๋ ์ ์ ํผํ์ฌ TTI๋ฅผ ์ง์ ์ ์ผ๋ก ๊ฐ์ ํฉ๋๋ค.
Hermes V1์ ์ํ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ ํจํด
Hermes V1์ ์ง์ฐ ํจ์ ์ปดํ์ผ์ ๋์ ํ์ต๋๋ค. ํจ์๋ ์ฒ์ ํธ์ถ๋ ๋๋ง ์์ ํ ์ปดํ์ผ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๊ฑฐ์ ์ฌ์ฉ๋์ง ์๋ ์ฝ๋ ๊ฒฝ๋ก๊ฐ ๋ง์ ์ฝ๋๋ฒ ์ด์ค์ ์ด๊ธฐ ๋ฉ๋ชจ๋ฆฌ ํํ๋ฆฐํธ๊ฐ ํฌ๊ฒ ๊ฐ์ํ์ง๋ง, ๊ฐ๋ฐ์๋ ๊ทธ ์ํฅ์ ์ดํดํด์ผ ํฉ๋๋ค.
// These functions compile only when the feature is accessed
export function initializeAdvancedAnalytics() {
// Complex initialization logic - compiled on first call
const analyticsEngine = require('./AnalyticsEngine');
return analyticsEngine.initialize({
samplingRate: 0.1,
batchSize: 50,
});
}
export function generateDetailedReport(data) {
// Heavy computation - memory allocated only when needed
const ReportGenerator = require('./ReportGenerator');
return new ReportGenerator(data).generate();
}
// In component - feature flags control compilation timing
function SettingsScreen({ hasAdvancedFeatures }) {
const [analytics, setAnalytics] = useState(null);
useEffect(() => {
if (hasAdvancedFeatures && !analytics) {
// Function compiles here, not at module load
setAnalytics(initializeAdvancedAnalytics());
}
}, [hasAdvancedFeatures]);
return (
<View>
{hasAdvancedFeatures && analytics && (
<AnalyticsDashboard data={analytics} />
)}
</View>
);
}Hermes ๋ฐ์ดํธ์ฝ๋๋ ์ผ๋ฐ์ ์ผ๋ก ๋๋ฑํ ๋ฏธ๋ํ์ด๋ JavaScript๋ณด๋ค 10~30% ๋ ์์ต๋๋ค. ์ด๋ฌํ ๋ฒ๋ค ํฌ๊ธฐ ๊ฐ์๋ก ์ฑ ์คํ ์ด์์ ๋ค์ด๋ก๋๋ถํฐ ์ฒซ ์คํ๊น์ง์ ์ ํ์จ์ด ํฅ์๋๊ณ , ์คํ ๋ฆฌ์ง๊ฐ ๋๋ฆฐ ๊ธฐ๊ธฐ์์ ์ฝ๋ ์คํํธ ์๊ฐ์ด ๋จ์ถ๋ฉ๋๋ค.
React Native ๋ฉด์ ์ค๋น๊ฐ ๋์ จ๋์?
์ธํฐ๋ํฐ๋ธ ์๋ฎฌ๋ ์ดํฐ, flashcards, ๊ธฐ์ ํ ์คํธ๋ก ์ฐ์ตํ์ธ์.
ํ๋ก๋์ ๋น๋์์ ๋ฐ์ดํธ์ฝ๋ ์ปดํ์ผ ๊ฒ์ฆํ๊ธฐ
ํํ ์ค์๋ Hermes ๋ฐ์ดํธ์ฝ๋๊ฐ ์๋์ผ๋ก ๋ฐฐํฌ๋๋ค๊ณ ๊ฐ์ ํ๋ ๊ฒ์ ๋๋ค. ๋๋ฒ๊ทธ ๋น๋์์๋ ๋น ๋ฅธ ๋ฐ๋ณต์ ์ํด ์ผ๋ฐ JavaScript๋ฅผ ์ฌ์ฉํ ์ ์์ด, ๊ฐ๋ฐ์๊ฐ ํ๋ก๋์ ํ๊ฒฝ๊น์ง ๋ฐ์ดํธ์ฝ๋ ๊ด๋ จ ๋ฌธ์ ๋ฅผ ์ธ์งํ์ง ๋ชปํ ์ ์์ต๋๋ค. ๊ฒ์ฆ์ ์ํด์๋ ์ค์ ๋ฒ๋ค ๋ด์ฉ์ ํ์ธํด์ผ ํฉ๋๋ค.
# Android: Check for Hermes bytecode in APK
unzip -l app-release.apk | grep -E "bundle$|hbc$"
# Expected: assets/index.android.bundle (should be HBC format)
# Verify file is actually bytecode, not plain JS
unzip -p app-release.apk assets/index.android.bundle | head -c 8 | xxd
# Hermes bytecode starts with magic bytes: c6 1f bc 03
# iOS: Check for bytecode in IPA
unzip -l App.ipa | grep -E "main.jsbundle"
# Extract and verify magic bytes same as Android๋ฒ๋ค์ด ๋ฐ์ดํธ์ฝ๋๊ฐ ์๋ ์ผ๋ฐ JavaScript์ธ ๊ฒฝ์ฐ, ๋น๋ ์ค์ ์์ Hermes๊ฐ ๋นํ์ฑํ๋์ด ์๊ฑฐ๋ Metro ํธ๋์คํฌ๋จธ ์ค๋ฒ๋ผ์ด๋๊ฐ hermesc๋ฅผ ์ฐํํ๊ณ ์์ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. react-native.config.js๋ฅผ ํ์ธํ๊ณ ์ปค์คํ
ํธ๋์คํฌ๋จธ๊ฐ ๋ฐ์ดํธ์ฝ๋ ์์ฑ์ ๋ฐฉํดํ์ง ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
module.exports = {
// Do NOT set hermes_enabled: false
// Hermes is default in 0.84+
project: {
ios: {},
android: {},
},
// Custom assets configuration if needed
assets: ['./src/assets/fonts'],
};Hermes V1 ๊ด๋ จ ๊ธฐ์ ๋ฉด์ ์ง๋ฌธ
์๋์ด React Native ํฌ์ง์ ์์๋ Hermes ๊ด๋ จ ์ง๋ฌธ์ด ์ ์ ์ฆ๊ฐํ๊ณ ์์ต๋๋ค. ์ด๋ฌํ ์ง๋ฌธ๋ค์ ์ฑ ์ฑ๋ฅ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์น๋ JavaScript ์์ง ๊ณ์ธต์ ๋ํ ์ดํด๋๋ฅผ ํ๊ฐํฉ๋๋ค.
์ง๋ฌธ 1: Hermes ๋ฐ์ดํธ์ฝ๋ ์ปดํ์ผ๊ณผ V8 JIT ์ปดํ์ผ์ ์ฐจ์ด์ ์ ์ค๋ช ํ์ญ์์ค
Hermes๋ AOT(Ahead-of-Time) ์ปดํ์ผ์ ์ฌ์ฉํฉ๋๋ค. JavaScript๋ ๊ฐ๋ฐ ๋จธ์ ์ด๋ CI ์๋ฒ์์ ๋น๋ ํ๋ก์ธ์ค ์ค์ ๋ฐ์ดํธ์ฝ๋๋ก ๋ณํ๋ฉ๋๋ค. ์ปดํ์ผ๋ ๋ฐ์ดํธ์ฝ๋๋ ์ฑ ๋ฐ์ด๋๋ฆฌ์ ํจ๊ป ๋ฐฐํฌ๋ฉ๋๋ค. ๋ฐํ์์ Hermes๋ JavaScript ์์ค๋ฅผ ํ์ฑํ์ง ์๊ณ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์ง์ ์คํํฉ๋๋ค.
V8์ JIT(Just-in-Time) ์ปดํ์ผ์ ์ฌ์ฉํฉ๋๋ค. JavaScript ์์ค๊ฐ ์ฑ๊ณผ ํจ๊ป ๋ฐฐํฌ๋ฉ๋๋ค. ๋ฐํ์์ V8์ ์์ค๋ฅผ ํ์ฑํ๊ณ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์์ฑํ ๋ค์, ๋จ๊ณ์ ์ปดํ์ผ(Ignition ์ธํฐํ๋ฆฌํฐ โ TurboFan ์ต์ ํ ์ปดํ์ผ๋ฌ)์ ํตํด ํซ ํจ์๋ฅผ ์ ์ง์ ์ผ๋ก ์ต์ ํํฉ๋๋ค.
ํธ๋ ์ด๋์คํ: Hermes๋ ํผํฌ ์คํ ์๋๋ฅผ ํฌ์ํ๊ณ ์ผ๊ด๋ ์์ ์ฑ๋ฅ์ ๋ฌ์ฑํฉ๋๋ค. V8์ JIT๋ ๊ฒฐ๊ตญ Hermes ๋ฐ์ดํธ์ฝ๋๋ณด๋ค ํซ ๊ฒฝ๋ก๋ฅผ ๋ ๋น ๋ฅด๊ฒ ์คํํ ์ ์์ง๋ง, ์์ ์๊ฐ๊ณผ ์ต์ ํ ์ปดํ์ผ๋ฌ๋ฅผ ์ํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. ๋ชจ๋ฐ์ผ ์ฑ์ ํผํฌ ์ฒ๋ฆฌ๋๋ณด๋ค ๋น ๋ฅธ ์์์์ ๋ ํฐ ์ด์ ์ ์ป์ต๋๋ค. ์ฌ์ฉ์๋ ์ธํฐ๋ํฐ๋ธ ์ํ๊ฐ ๋๊ธฐ๊น์ง 3์ด ์ด์ ๊ฑธ๋ฆฌ๋ ์ฑ์ ์ดํํ๋ ๊ฒฝํฅ์ด ์์ต๋๋ค.
์ง๋ฌธ 2: Hades GC๊ฐ GenGC์ ์ด๋ป๊ฒ ๋ค๋ฅด๋ฉฐ, ์ ๋ณ๊ฒฝ์ด ํ์ํ์ต๋๊น?
GenGC๋ ์ฑ๊ธ ์ค๋ ๋์ ๋๋ค. ๋ชจ๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ์์ ์ด JavaScript ์คํ์ ์ค๋จํฉ๋๋ค. ๋งํฌ ๋จ๊ณ๋ ๊ฐ์ฒด ๊ทธ๋ํ๋ฅผ ์ํํ๊ณ , ์ปดํฉํธ ๋จ๊ณ๋ ํ์ ์กฐ๊ฐ ๋ชจ์ํฉ๋๋ค. ๋ ๋ค ๋ฉ์ธ ์ค๋ ๋์์ ์ํ๋ฉ๋๋ค. ๋ณต์กํ ์ฑ์์ GC ์ผ์ ์ ์ง๋ ์๋ฐฑ ๋ฐ๋ฆฌ์ด์ ๋ฌํ์ต๋๋ค.
Hades๋ ๋๋ถ๋ถ ๋์์ฑ์ผ๋ก ๋์ํฉ๋๋ค. ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋๊ฐ JavaScript ์คํ ์ค์ ๋งํฌ ์ค์ ์ปฌ๋ ์ ์ ์ํํฉ๋๋ค. ๋ฃจํธ ๋งํน๊ณผ ์ฝํ ์ฐธ์กฐ ํ์ด๋๋ผ์ด์ ์ด์ ์ ์ํด ์งง์ ์คํฑ ๋ ์๋ ์ผ์ ์ ์ง๊ฐ ๋จ์ ์์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก 10ms ๋ฏธ๋ง์ ๋๋ค. ์ ์ ๋๋ ์ด์ ์ ์ฌ์ ํ ๋ณต์ฌ ์ปฌ๋ ์ (๋น ๋ฅด์ง๋ง ์ผ์ ์ ์ง ํ์)์ ์ฌ์ฉํ๊ณ , ์ฌ๋ ์ ๋๋ ์ด์ ์ ๋์์ฑ ๋งํฌ ์ค์์ ์ฌ์ฉํฉ๋๋ค.
์ด ๋ณ๊ฒฝ์ด ํ์ํ๋ ์ด์ ๋ ๋ชจ๋ฐ์ผ UI ํ๋ ์์ํฌ๊ฐ 60fps ์ ๋๋ฉ์ด์ ์ ์ํด 16ms ํ๋ ์ ์์ฐ์ ์๊ตฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค. 200ms๋ฅผ ์ด๊ณผํ๋ GenGC ์ผ์ ์ ์ง๋ ๋์ ๋ณด์ด๋ ๋ฒ๋ฒ ๊ฑฐ๋ฆผ๊ณผ ๋ฎ์ ์ฌ์ฉ์ ๊ฒฝํ ํ๊ฐ๋ฅผ ์ด๋ํ์ต๋๋ค.
์ง๋ฌธ 3: Hermes์์ ํ๋ฆฌํ ๋ด์ด๋ง์ด๋ ๋ฌด์์ด๋ฉฐ ์ธ์ ์กฐ์ ํด์ผ ํฉ๋๊น?
ํ๋ฆฌํ ๋ด์ด๋ง์ ์ฒซ 32MiB๋ฅผ ์ ์ ๋๋ ์ด์ ์ปฌ๋ ์ ์ ๊ฑด๋๋ฐ๊ณ ์ฌ๋ ์ ๋๋ ์ด์ ์ ์ง์ ํ ๋นํฉ๋๋ค. React Native ์ด๊ธฐํ๋ ์ ์ ๋๋ ์ด์ ์ปฌ๋ ์ ์ ์ด์ ์ ๋ฐ์ง ๋ชปํ๋ ์ค๋ ์ด์๋จ๋ ๊ฐ์ฒด(๋ด๋น๊ฒ์ด์ ์ํ, Redux ์คํ ์ด, API ํด๋ผ์ด์ธํธ)๋ฅผ ์์ฑํฉ๋๋ค. ํ๋ฆฌํ ๋ด์ด๋ง์ ์์ ์ ์ปฌ๋ ์ ์์ ์คํ์ ๋ฐฉ์งํฉ๋๋ค.
์กฐ์ ์๋๋ฆฌ์ค: ๋น์ ์์ ์ผ๋ก ํฐ ์ด๊ธฐํ ํ ๋น(๋ฌด๊ฑฐ์ด ๋ค์ดํฐ๋ธ ๋ชจ๋ ์ค์ , ํฐ ์ ์ ๋ฐ์ดํฐ์ )์ด ์๋ ์ฑ์ ํ๋ฆฌํ ๋ด์ด ํฌ๊ธฐ ์ฆ๊ฐ๋ก ์ด์ ์ ์ป์ ์ ์์ต๋๋ค. ์ต์ ๋ฉ๋ชจ๋ฆฌ ํํ๋ฆฐํธ์ ์ต์ ํ๋ ์ฑ์ ์ด๋ฅผ ์ค์ผ ์ ์์ต๋๋ค. ์ค์ ๋ก 32MiB ๊ธฐ๋ณธ๊ฐ์ ๋๋ถ๋ถ์ ์ฑ์์ ์ ์๋ํ๋ฉฐ, ๋ณ๊ฒฝ ์ ์ ์ค์ ๊ธฐ๊ธฐ ๋ฉํธ๋ฆญ์ ์ฌ์ฉํ ํ๋กํ์ผ๋ง์ด ์ ํ๋์ด์ผ ํฉ๋๋ค.
์ง๋ฌธ 4: Hermes ๊ธฐ๋ฐ React Native ์ฑ์์ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋๋ฒ๊น ํ๋ ๋ฐฉ๋ฒ์?
React Native ๋ด์ฅ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ฅผ ์ฌ์ฉํ์ฌ JS ํ ํฌ๊ธฐ ์ถ์ธ๋ฅผ ๊ด์ฐฐํ๋ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. ์ ์ ์ฌ์ฉ ์ค์ ํ์ด ์ฆ๊ฐํ๋ฉด ๋์๋ฅผ ๋ํ๋ ๋๋ค. Flipper์ Hermes ๋๋ฒ๊ฑฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋์๊ฐ ์์ฌ๋๋ ์๋๋ฆฌ์ค ์ ํ์ ํ ์ค๋ ์ท์ ์บก์ฒํฉ๋๋ค.
React Native์์ ํํ ๋์ ํจํด:
- ์ ๋ฆฌ ํจ์์์ ์ ๊ฑฐ๋์ง ์๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋
- ์ค๋ ์ด์๋จ๋ ์ฝ๋ฐฑ์์ ์ปดํฌ๋ํธ ์ํ๋ฅผ ์บก์ฒํ๋ ํด๋ก์
- ํ๋ฉด ์ธ๋ง์ดํธ ํ์๋ ์ ์ง๋๋ ๋ด๋น๊ฒ์ด์ ๋ฆฌ์ค๋
- ์ธ๋ง์ดํธ ์ ์ค์ง๋์ง ์๋ ์ ๋๋ฉ์ด์ ๊ฐ
// Memory leak pattern - closure captures component scope
function LeakyComponent() {
const [data, setData] = useState(largeDataset);
useEffect(() => {
// This closure captures 'data' - if interval persists, so does data
const interval = setInterval(() => {
console.log(data.length); // Leak: data never GC'd while interval runs
}, 1000);
// Fix: clear interval on unmount
return () => clearInterval(interval);
}, [data]);
}์ง๋ฌธ 5: Hermes์์ ๋ค์ดํฐ๋ธ ๋ชจ๋์ ์ฌ์ฉํ ๋ ์ค๋ ๋ฉ ๊ด๋ จ ๊ณ ๋ ค ์ฌํญ์?
Hades๋ JavaScript ๊ฐ์ฒด๋ฅผ ์์ฑ๋ ์ค๋ ๋๊ฐ ์๋ ๋ฐฑ๊ทธ๋ผ์ด๋ GC ์ค๋ ๋์์ ํ๊ดดํฉ๋๋ค. ์ค๋ ๋ ๋ก์ปฌ ๋ฆฌ์์ค(GPU ์ปจํ ์คํธ, ๋ค์ดํฐ๋ธ ํธ๋ค)๋ฅผ ์ ์งํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ ๋ฆฌ ์ฝ๋๊ฐ ์ฑ๊ธ ์ค๋ ๋ ํ๊ดด๋ฅผ ๊ฐ์ ํ๋ฉด ํฌ๋์ํ ์ ์์ต๋๋ค.
์ฃผ๋ชฉํ ๋งํ ์์: React Native Skia๋ ์ค๋ ๋๋ณ๋ก GPU ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. UI ์ค๋ ๋์์ ์์ฑ๋ ๊ฐ์ฒด๋ UI ์ค๋ ๋์์ ํ๊ดด๋์ด์ผ ํฉ๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ ๋ฆฌ๋ฅผ ์ํ ์ฌ๋ฐ๋ฅธ ์ค๋ ๋ ์ดํผ๋ํฐ๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ํน๋ณํ ์ฐธ์กฐ ์นด์ดํ ์ ๊ตฌํํฉ๋๋ค.
์ปค์คํ
๋ค์ดํฐ๋ธ ๋ชจ๋์ ์์ฑํ ๋, ์๋ฉธ์ ๋ก์ง์ด ์ฌ๋ฐ๋ฅธ ์ค๋ ๋์์ ์คํ๋๊ฑฐ๋ ์ค๋ ๋ ์ธ์ดํํ์ง ํ์ธํด์ผ ํฉ๋๋ค. ํน์ ์ค๋ ๋ ์ดํผ๋ํฐ๊ฐ ํ์ํ ์ ๋ฆฌ์๋ ํ๋ซํผ๋ณ ์ค๋ ๋ ๋์คํจ์น(Android: Handler.post(), iOS: dispatch_async())๋ฅผ ์ฌ์ฉํ์ญ์์ค.
์ฑ๋ฅ ๋ฒค์น๋งํฌ: Hermes V1 vs ์ด์ ๋ฒ์
์ค์ ์ธก์ ์ ํตํด ์ฃผ์ ๋ฉํธ๋ฆญ ์ ๋ฐ์ ๊ฑธ์น Hermes V1 ๊ฐ์ ์ฌํญ์ด ์ ์ฆ๋์์ต๋๋ค:
| ๋ฉํธ๋ฆญ | Hermes Legacy | Hermes V1 | ๊ฐ์ | |--------|---------------|-----------|-------------| | ์ฝ๋ ์คํํธ (TTI) | 2.8์ด | 1.9์ด | 32% ๋จ์ถ | | ์ ์คํํธ | 1.2์ด | 0.8์ด | 33% ๋จ์ถ | | JS ํ ํฌ๊ธฐ | 45MB | 38MB | 16% ๊ฐ์ | | GC ์ผ์ ์ ์ง (p99) | 180ms | 12ms | 93% ๊ฐ์ | | ๋ฒ๋ค ํฌ๊ธฐ | 4.2MB | 3.1MB | 26% ๊ฐ์ |
๋ฒค์น๋งํฌ๋ Pixel 6a(Android)์ iPhone 12(iOS)์์ ํ ์คํธ๋ ์ค๊ฐ ๋ณต์ก๋์ ์ด์ปค๋จธ์ค ์ฑ ๊ธฐ์ค์ ๋๋ค. ๊ฒฐ๊ณผ๋ ๋ฒ๋ค ํฌ๊ธฐ, ํ๋ฉด ์, ๋ค์ดํฐ๋ธ ๋ชจ๋ ์ฌ์ฉ๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
JSC์์ ๋ง์ด๊ทธ๋ ์ด์ ํ๋ ํ์ ๊ฒฝ์ฐ ๊ฐ์ ํจ๊ณผ๊ฐ ๋์ฑ ๊ทน์ ์ ๋๋ค. ํนํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ํ๋ Android ๊ธฐ๊ธฐ์์ ์ด์ ์ 500ms๋ฅผ ์ด๊ณผํ๋ GC ์ผ์ ์ ์ง์์ ๋๋๋ฌ์ง ๊ฐ์ ์ ํ์ธํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
- Hermes V1์ ํ๋ฆฌ์ปดํ์ผ๋ ๋ฐ์ดํธ์ฝ๋๋ฅผ ๋ฐฐํฌํ์ฌ ๋ฐํ์ JavaScript ํ์ฑ์ ์ ๊ฑฐํ๊ณ Time to Interactive๋ฅผ 25~50% ๋จ์ถํฉ๋๋ค
- Hades ๋์์ฑ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ผ์ ์ ์ง๋ฅผ ์๋ฐฑ ๋ฐ๋ฆฌ์ด์์ p99 ๊ธฐ์ค 12ms ๋ฏธ๋ง์ผ๋ก ์ค์ฌ ๋ถ๋๋ฌ์ด 60fps ์ ๋๋ฉ์ด์ ์ ์ ์งํฉ๋๋ค
- ํ๋ฆฌํ ๋ด์ด๋ง(๊ธฐ๋ณธ 32MiB)์ ์ด๊ธฐํ ๊ฐ์ฒด๋ฅผ ์ฌ๋ ์ ๋๋ ์ด์ ์ ์ง์ ํ ๋นํ์ฌ ์์์ ์ต์ ํํฉ๋๋ค
- ํ๋ก๋์
๋น๋๊ฐ ์ผ๋ฐ JavaScript๊ฐ ์๋
.hbc๋ฐ์ดํธ์ฝ๋๋ฅผ ํฌํจํ๋์ง ๋งค์ง ๋ฐ์ดํธ(c6 1f bc 03)๋ฅผ ํ์ธํ์ฌ ๊ฒ์ฆํด์ผ ํฉ๋๋ค - ์ง์ฐ ํจ์ ์ปดํ์ผ๋ก ์ด๊ธฐ ๋ฉ๋ชจ๋ฆฌ ํํ๋ฆฐํธ๊ฐ ๊ฐ์ํฉ๋๋ค. ๊ฑฐ์ ์ฌ์ฉ๋์ง ์๋ ๊ธฐ๋ฅ์ ์ปดํ์ผ์ ์ง์ฐ์ํค๋๋ก ์ฝ๋๋ฅผ ๊ตฌ์กฐํํด์ผ ํฉ๋๋ค
- ๋ค์ดํฐ๋ธ ๋ชจ๋ ์์ฑ์๋ ์ค๋ ๋ ๋ก์ปฌ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์์ ๊ฐ์ฒด ํ๊ดด๋ฅผ ๊ณ ๋ คํด์ผ ํฉ๋๋ค
- ๊ธฐ์ ๋ฉด์ ์์๋ Hermes ๋ด๋ถ์ ๋ํ ํ๊ฐ๊ฐ ์ฆ๊ฐํ๊ณ ์์ต๋๋ค: ๋ฐ์ดํธ์ฝ๋ vs JIT ํธ๋ ์ด๋์คํ, GC ์ํคํ ์ฒ, ๋ฉ๋ชจ๋ฆฌ ๋๋ฒ๊น ์ํฌํ๋ก์ฐ๊ฐ ์ฃผ์ ์ฃผ์ ์ ๋๋ค
์ฐ์ต์ ์์ํ์ธ์!
๋ฉด์ ์๋ฎฌ๋ ์ดํฐ์ ๊ธฐ์ ํ ์คํธ๋ก ์ง์์ ํ ์คํธํ์ธ์.
ํ๊ทธ
๊ณต์
๊ด๋ จ ๊ธฐ์ฌ

React Native 0.86 ์๋ฒฝ ๊ฐ์ด๋ 2026: Android 15 ์ฃ์งํฌ์ฃ์ง ์ง์๊ณผ DevTools ํ์ฉ๋ฒ
React Native 0.86์ Android 15 ์ฃ์งํฌ์ฃ์ง ์ง์, DevTools ๊ฐ์ ์ฌํญ, ๋ฉด์ ๋๋น ์ง๋ฌธ์ ์์ธํ ๋ค๋ฃน๋๋ค. ์ค์ฉ์ ์ธ ์ฝ๋ ์์ ์ ์ต์ ๋ฒ ์คํธ ํ๋ํฐ์ค๋ฅผ ์๊ฐํฉ๋๋ค.

React Native์ TypeScript 2026: ํ์ ์์ ํ ์ํคํ ์ฒ์ ๋ฉด์ ์ง๋ฌธ
2026๋ React Native์์ TypeScript๋ฅผ ํ์ฉํ ํ์ ์์ ์ํคํ ์ฒ๋ฅผ ๋ค๋ฃน๋๋ค. Codegen, TurboModules, Strict TypeScript API, ํ์ ์์ ๋ด๋น๊ฒ์ด์ , ๋ฉด์ ์ง๋ฌธ์ ์ฝ๋ ์์ ์ ํจ๊ป ์ค๋ช ํฉ๋๋ค.

React Native 0.85 (2026): ์๋ก์ด ์ ๋๋ฉ์ด์ ๋ฐฑ์๋, ์๊ฒฉํ TypeScript API ๋ฐ ๋ฉด์ ์ง๋ฌธ
React Native 0.85์ ๊ณต์ ์ ๋๋ฉ์ด์ ๋ฐฑ์๋, ํฌ์คํธ ๋ธ๋ฆฌ์ง ์ํคํ ์ฒ, Metro TLS์ ๋ํด ์ฝ๋ ์์ ์ ๋ฉด์ ์ง๋ฌธ์ ํตํด ์ฌ์ธต ๋ถ์ํฉ๋๋ค.