Hermes — ay isang JavaScript engine na may AOT compilation (Ahead-of-Time), na binuo ng Meta para sa React Native at na-optimize para sa mga mobile device na may limitadong memorya. Ayon sa opisyal na blog ng Meta Engineering (2022), binabawasan ng Hermes ang oras ng pag-start ng app ng 20-50% at pinaliit ang laki ng bundle ng 30-40% kumpara sa JavaScriptCore. Hindi tulad ng V8 o JSC, hindi gumagamit ang Hermes ng JIT compilation sa device — lahat ng JavaScript ay na-compile sa bytecode sa yugto ng build sa pamamagitan ng Hermes CLI. Ito ay lalong mahalaga para sa iOS, kung saan ang JIT compilation ay limitado ng mga patakaran ng App Store.
Mga Pangunahing Punto
Hermes — ay isang compact JavaScript engine na may open source (MIT license), nilikha ng Meta para sa React Native at na-optimize para sa paggana sa mga mobile device na may limitadong resources. Ang pangunahing inobasyon ng Hermes ay ang pagtalikod sa JIT compilation pabor sa AOT (Ahead-of-Time). Sa yugto ng pagbuo ng React Native app, ang Metro Bundler ay nagpapadala ng naka-compile na JavaScript sa Hermes CLI, na nagko-convert nito sa HBC bytecode (Hermes ByteCode). Ang bytecode na ito ay direktang isinasagawa ng engine nang walang karagdagang compilation sa device. Ang pamamaraang ito ay nagbibigay ng predictable na pagganap: walang “pag-init” ng JIT, walang mga pause sa compilation, walang karagdagang konsumo ng baterya. Ang Hermes ay dinisenyo na isinasaalang-alang ang mga limitasyon ng mga mobile device: maliit na RAM (1-4 GB), limitadong konsumo ng kuryente at pangangailangan para sa mabilis na cold start. Ang unang pampublikong release ng Hermes ay noong 2019, at mula sa React Native 0.70 (2022) ang engine ay naging standard sa Android.
JavaScriptCore (JSC) — ang standard na WebKit engine, ginagamit ng Safari at React Native bago ang bersyon 0.70. Sinusuportahan ng JSC ang JIT compilation, na nagbibigay ng mataas na pagganap para sa mga kumplikadong JavaScript operations. Gayunpaman, ang JIT ay nangangailangan ng pag-init: ang mga unang segundo ay mas mabagal ang pagtakbo ng code (interpreted mode), pagkatapos ay kino-compile ng JIT ang mga mainit na bahagi. Sa iOS, ang JIT ay halos hindi available dahil sa mga patakaran ng App Store (pagbabawal sa dynamic na code generation), kaya ang JSC sa iOS ay gumagana lamang sa interpreted mode — bumababa ang pagganap. Ang JSC ay may mas malaking binary size (mga 10 MB) at kumokonsumo ng mas maraming RAM dahil sa JIT infrastructure. Ang Hermes ay hindi nakadepende sa JIT, na nagbibigay ng predictable na pagganap kaagad pagkatapos ng startup (cold start). Mas buong sinusuportahan ng JSC ang ECMAScript standard (kabilang ang Proxy, BigInt, Reflect), ngunit sa halaga ng mas malaking resource consumption. Para sa mga React Native project kung saan kritikal ang cold start at maliit na laki — mas gusto ang Hermes. Para sa mga project na may mabibigat na JS computations (laro, WebGL) — ang JSC ay maaaring magbigay ng mas mataas na peak performance.
| Parameter | Hermes | JavaScriptCore |
|---|---|---|
| Compilation | AOT (sa yugto ng build) | JIT + Interpreted (sa device) |
| Cold start | 20-50% mas mabilis | Base level |
| Laki ng bundle | 30-40% mas maliit | Base level |
| Konsumo ng RAM | 20-30% mas kaunti | Base level |
| ECMAScript | ES2020 (mga limitasyon) | ES2022+ (buo) |
| iOS JIT | Hindi kinakailangan | Hindi available (interpreted lang) |
| Binary | ~3 MB | ~10 MB |
AOT compilation (Ahead-of-Time) sa Hermes ay nangyayari sa dalawang yugto. Sa unang yugto, kinokolekta ng Metro Bundler ang mga JavaScript file sa isang bundle at ipinapadala ito sa Hermes CLI (utility na hermesc). Sa ikalawang yugto, pina-parse ng hermesc ang JavaScript AST, gumagawa ng intermediate representation na HIR (Hermes Intermediate Representation) at pagkatapos ay naglalabas ng binary HBC bytecode. Ang resulta ay isang file na may extension na .hbc na naglalaman lamang ng bytecode na walang orihinal na JavaScript. Direktang nilo-load ng Hermes runtime ang HBC, nang walang pag-parse at compilation. Ito ay radikal na nagpapabilis ng startup: sa halip na mag-parse ng libu-libong linya ng JS (async), binabasa ng engine ang isang pre-compiled binary format. Binabawasan din ng AOT ang laki: ang bytecode ay average na 30% na mas compact kaysa sa JavaScript AST. Ang disadvantage ng AOT — hindi maaaring mag-execute ng eval, new Function o dynamic na require sa runtime — lahat ng module ay dapat na kilala sa yugto ng build.
# I-install ang Hermes CLI nang standalone
npm install hermes-engine
# I-compile ang JS sa HBC bytecode
npx hermesc -emit-binary -out bundle.hbc bundle.js
# Mga statistika ng bytecode
npx hermesc -dump-bytecode bundle.hbc # shows HBC instructions
# Laki ng orihinal na JS vs HBC
wc -c bundle.js # 2,300,000 bytes
wc -c bundle.hbc # 1,450,000 bytes (37% reduction)
Ang pagganap ng Hermes ay sinusukat sa tatlong pangunahing metrik: Time-To-Interactive (TTI), laki ng APK/IPA at konsumo ng RAM. Ayon sa Meta, sa Android binabawasan ng Hermes ang TTI ng 34% kumpara sa JSC: mula 4.2 segundo hanggang 2.8 segundo sa isang mid-range na device (Moto G7). Bumababa ang laki ng APK ng 28% dahil sa compact bytecode at kawalan ng JIT libraries. Ang konsumo ng RAM ay average na 22% na mas mababa sa parehong load — ito ay lalong mahalaga para sa mga device na may 2-3 GB RAM. Sa iOS, ang advantage ay mas malaki: dahil hindi magamit ng JSC ang JIT, ang Hermes ay nagbibigay ng TTI improvement na hanggang 45%. Ang mga metrik ay batay sa mga pagsubok ng Meta sa Facebook Lite app. Sa totoong project, ang advantage ay nag-iiba: para sa mga simpleng screen (mga listahan, text) ang Hermes ay nagbibigay ng mas malaking improvement, para sa mabibigat na animation — mas maliit. Profiling tool: React Native Profiler + hermes profile --heap.
Hermes ay may kasamang built-in memory profiler, naa-access sa pamamagitan ng Chrome DevTools. Kumonekta sa app sa pamamagitan ng Metro, buksan ang tab na Memory at piliin ang Hermes (JavaScript) sa mga uri ng snapshot. Sinusuportahan ng Hermes ang tatlong uri ng snapshot: Heap Snapshot (lahat ng objects), Allocation Timeline (habang-buhay ng mga object) at Allocation Sampling (selective profile). Binabawasan ng Hades GC ang bilang ng mga GC pause sa minimum — average na isang pause na 2-5ms bawat 10 segundo ng trabaho kumpara sa mga pause na 10-20ms sa JSC sa parehong panahon.
Hades GC — ay ang garbage collector sa Hermes, dinisenyo para sa mga mobile scenario na may minimal na mga pause. Hindi tulad ng mark-sweep GC sa JSC, ang Hades ay gumagamit ng concurrent collection: ang collector ay gumagana nang parallel sa main execution thread, pinipigilan lamang ito sa maikling panahon. Hinahati ng Hades GC ang heap sa mga generation: ang batang generation (nursery) ay kinokolekta nang madalas at mabilis (Scavenge), ang lumang generation ay kinokolekta nang mas madalang at may mas maliliit na pause. Ang laki ng heap ay configurable: bilang default — 2/3 ng available na RAM ng app, minimum threshold — 32 MB. Hindi ginagamit ng Hades ang stop-the-world approach: kahit ang buong collection ng lumang generation ay hindi hihigit sa 5-8ms. Ang collector ay na-optimize para sa tipikal na mobile scenario: maraming panandaliang object (temporary strings, React fibre objects), kakaunting matagalang object. Para sa mga app na may intensive object creation (mga listahan, animation) ang Hades ay nagbibigay ng mas smooth na FPS kumpara sa JSC.
Ang pag-enable ng Hermes ay depende sa bersyon ng React Native at platform. Mula sa React Native 0.70, ang Hermes ay naka-enable bilang default para sa Android sa mga bagong project. Para sa iOS, ang Hermes ay opsyonal. Para i-enable sa Android: sa file na android/app/build.gradle itakda ang enableHermes: true sa block na project.ext.react.enableHermes. Para sa iOS: itakda ang hermes_enabled sa true sa Podfile sa pamamagitan ng use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true). Pagkatapos i-enable, isagawa ang pod install. Para sa mga umiiral na project, suriin ang compatibility ng mga library: hindi sinusuportahan ng Hermes ang Proxy, eval at ilang ES2021 feature. Gamitin ang npx react-native info para suriin ang configuration. Para lumipat sa pagitan ng Hermes at JSC, baguhin ang flag at magsagawa ng clean rebuild.
// android/app/build.gradle — i-enable ang Hermes
project.ext.react = [
enableHermes: true,
cliPath: "node_modules/react-native/cli.js"
]
// iOS/Podfile — i-enable ang Hermes sa iOS
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
target 'MyApp' do
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
:hermes_enabled => true
)
end
Ang mga pangunahing limitasyon ng Hermes ay nauugnay sa pagtalikod sa JIT. Hindi sinusuportahan ng Hermes ang: Proxy at Reflect API (ginagamit sa MobX, Vue, ilang state manager), BigInt (malalaking numero), Symbol.toStringTag, WeakRef at FinalizationRegistry. Ang mga function na eval at new Function ay bumubuo ng exception sa panahon ng execution. Ang mga callback ng mga method na Array.prototype.flat at flatMap na may argumentong this ay gumagana nang may mga limitasyon. Ang mga format ng petsa ng ISO 8601 na may time zone ay hindi ganap na napoproseso. Karamihan sa mga limitasyong ito ay hindi nakakaapekto sa mga tipikal na React Native app: ang React at React Native ay gumagamit ng limitadong set ng ES features. Kung ang isang library ay nangangailangan ng Proxy (hal. MobX 6+ na may Proxy), gamitin ang configure({ useProxies: false }) o pumili ng alternatibo. Para suriin ang compatibility ng umiiral na code, isagawa ang npx hermesc -check sa iyong bundle — magpapakita ito ng listahan ng mga hindi suportadong feature.
Mga Madalas Itanong
Sa console ng app, isagawa ang console.log(global.HermesInternal). Kung ang object na HermesInternal ay umiiral — ang app ay tumatakbo sa Hermes. Alternatibo: console.log(global.HermesInternal?.getRuntimeProperties()) — magpapakita ng bersyon ng engine at mga parameter ng GC. Sa Release builds, ang HermesInternal ay maaaring hindi available upang mabawasan ang laki.
Suriin ang mga setting ng Podfile: ang Hermes sa iOS ay nangangailangan ng New Architecture (Fabric Renderer). Itakda ang :hermes_enabled => true, isagawa ang pod install --repo-update. Kung ang project ay na-update mula sa React Native na mas mababa sa 0.70, suriin ang compatibility ng mga library sa New Architecture. Huwag paganahin ang Hermes kung ang isang third-party library ay nangangailangan ng JSC — para dito, baguhin ang flag sa false at muling i-install ang Pods.
Hindi, hindi nakakaapekto ang Hermes sa Hot Reload / Fast Refresh. Sa panahon ng development, pinapatakbo ng Metro ang JavaScript bundle nang walang Hermes compilation (plain JS). Ang Hermes bytecode ay nilikha lamang para sa Release builds. Sa Debug mode, ginagamit ang standard na JavaScriptCore o Hermes sa interpreted mode. Ang bilis ng Hot Reload ay hindi nagbabago kapag ang Hermes ay naka-enable sa configuration — ang paglipat ay nangyayari lamang sa yugto ng production build.
Oo, mula sa Expo SDK 45 ang Hermes ay suportado para sa managed workflow. Sa app.json itakda ang "jsEngine": "hermes". Para sa bare workflow, ang Hermes ay gumagana tulad sa isang regular na React Native project. Hindi sinusuportahan ng Expo Go ang Hermes — gamitin ang Expo Dev Client o EAS Build para sa mga build na may Hermes. Suriin ang compatibility ng mga library sa pamamagitan ng expo doctor.
Gamitin ang React Native Performance Monitor (FPS metrics) at Hermes Profiling Tools. Gumawa ng dalawang bersyon ng app — na may Hermes at JSC — sa parehong device. Sukatin: cold start (mula sa pag-click ng icon hanggang sa unang interactive screen), TTI (Time-To-Interactive), laki ng APK/IPA at peak RAM consumption. Isagawa ang mga test nang hindi bababa sa 3 beses para sa bawat configuration. Karaniwang advantage ng Hermes: start 20-40% mas mabilis, RAM 15-25% mas kaunti.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din