Hermes — είναι μια μηχανή JavaScript με μεταγλώττιση AOT (Ahead-of-Time), που αναπτύχθηκε από τη Meta για το React Native και βελτιστοποιήθηκε για κινητές συσκευές με περιορισμένη μνήμη. Σύμφωνα με το επίσημο ιστολόγιο Meta Engineering (2022), το Hermes μειώνει τον χρόνο εκκίνησης της εφαρμογής κατά 20-50% και μειώνει το μέγεθος του πακέτου κατά 30-40% σε σύγκριση με το JavaScriptCore. Σε αντίθεση με το V8 ή το JSC, το Hermes δεν χρησιμοποιεί μεταγλώττιση JIT στη συσκευή — όλο το JavaScript μεταγλωττίζεται σε bytecode στο στάδιο της κατασκευής μέσω του Hermes CLI. Αυτό είναι ιδιαίτερα σημαντικό για το iOS, όπου η μεταγλώττιση JIT περιορίζεται από τις πολιτικές του App Store.
Κύρια σημεία
Hermes — είναι μια συμπαγής μηχανή JavaScript ανοιχτού κώδικα (άδεια MIT), που δημιουργήθηκε από τη Meta για το React Native και βελτιστοποιήθηκε για λειτουργία σε κινητές συσκευές με περιορισμένους πόρους. Η κύρια καινοτομία του Hermes είναι η εγκατάλειψη της μεταγλώττισης JIT υπέρ της AOT (Ahead-of-Time). Στο στάδιο κατασκευής της εφαρμογής React Native, το Metro Bundler μεταδίδει το μεταγλωττισμένο JavaScript στο Hermes CLI, το οποίο το μετατρέπει σε bytecode HBC (Hermes ByteCode). Αυτό το bytecode εκτελείται απευθείας από τη μηχανή χωρίς πρόσθετη μεταγλώττιση στη συσκευή. Αυτή η προσέγγιση παρέχει προβλέψιμη απόδοση: δεν υπάρχει “προθέρμανση” JIT, δεν υπάρχουν παύσεις μεταγλώττισης, δεν υπάρχει πρόσθετη κατανάλωση μπαταρίας. Το Hermes σχεδιάστηκε λαμβάνοντας υπόψη τους περιορισμούς των κινητών συσκευών: χαμηλή RAM (1-4 GB), περιορισμένη κατανάλωση ενέργειας και ανάγκη για γρήγορη ψυχρή εκκίνηση. Η πρώτη δημόσια κυκλοφορία του Hermes ήταν το 2019, και από το React Native 0.70 (2022) η μηχανή έγινε το πρότυπο στο Android.
JavaScriptCore (JSC) — η τυπική μηχανή WebKit, που χρησιμοποιείται από το Safari και το React Native πριν από την έκδοση 0.70. Το JSC υποστηρίζει μεταγλώττιση JIT, η οποία παρέχει υψηλή απόδοση για σύνθετες λειτουργίες JavaScript. Ωστόσο, το JIT απαιτεί προθέρμανση: τα πρώτα δευτερόλεπτα ο κώδικας εκτελείται πιο αργά (λειτουργία διερμηνείας), στη συνέχεια το JIT μεταγλωττίζει τα καυτά τμήματα. Στο iOS, το JIT είναι πρακτικά μη διαθέσιμο λόγω των πολιτικών του App Store (απαγόρευση δυναμικής παραγωγής κώδικα), επομένως το JSC στο iOS λειτουργεί μόνο σε λειτουργία διερμηνείας — η απόδοση μειώνεται. Το JSC έχει μεγαλύτερο δυαδικό μέγεθος (περίπου 10 MB) και καταναλώνει περισσότερη RAM λόγω της υποδομής JIT. Το Hermes δεν εξαρτάται από το JIT, παρέχοντας προβλέψιμη απόδοση αμέσως μετά την εκκίνηση (ψυχρή εκκίνηση). Το JSC υποστηρίζει πληρέστερα το πρότυπο ECMAScript (συμπεριλαμβανομένων των Proxy, BigInt, Reflect), αλλά με κόστος μεγαλύτερης κατανάλωσης πόρων. Για έργα React Native όπου η ψυχρή εκκίνηση και το μικρό μέγεθος είναι κρίσιμα — το Hermes είναι προτιμότερο. Για έργα με βαριούς υπολογισμούς JS (παιχνίδια, WebGL) — το JSC μπορεί να παρέχει υψηλότερη απόδοση αιχμής.
| Παράμετρος | Hermes | JavaScriptCore |
|---|---|---|
| Μεταγλώττιση | AOT (στο στάδιο κατασκευής) | JIT + Διερμηνεία (στη συσκευή) |
| Ψυχρή εκκίνηση | 20-50% ταχύτερη | Βασικό επίπεδο |
| Μέγεθος πακέτου | 30-40% μικρότερο | Βασικό επίπεδο |
| Κατανάλωση RAM | 20-30% λιγότερη | Βασικό επίπεδο |
| ECMAScript | ES2020 (περιορισμοί) | ES2022+ (πλήρες) |
| iOS JIT | Δεν απαιτείται | Μη διαθέσιμο (μόνο διερμηνεία) |
| Δυαδικό | ~3 MB | ~10 MB |
Μεταγλώττιση AOT (Ahead-of-Time) στο Hermes πραγματοποιείται σε δύο στάδια. Στο πρώτο στάδιο, το Metro Bundler συλλέγει τα αρχεία JavaScript σε ένα ενιαίο πακέτο και το μεταδίδει στο Hermes CLI (το βοηθητικό πρόγραμμα hermesc). Στο δεύτερο στάδιο, το hermesc αναλύει το AST JavaScript, δημιουργεί την ενδιάμεση αναπαράσταση HIR (Hermes Intermediate Representation) και στη συνέχεια εκπέμπει το δυαδικό bytecode HBC. Το αποτέλεσμα είναι ένα αρχείο με επέκταση .hbc που περιέχει μόνο bytecode χωρίς το αρχικό JavaScript. Το Hermes runtime φορτώνει το HBC απευθείας, χωρίς ανάλυση και μεταγλώττιση. Αυτό επιταχύνει ριζικά την εκκίνηση: αντί να αναλύει χιλιάδες γραμμές JS (async), η μηχανή διαβάζει μια προμεταγλωττισμένη δυαδική μορφή. Το AOT επίσης μειώνει το μέγεθος: το bytecode είναι κατά μέσο όρο 30% πιο συμπαγές από το JavaScript AST. Το μειονέκτημα του AOT — η αδυναμία εκτέλεσης eval, new Function ή δυναμικού require κατά τον χρόνο εκτέλεσης — όλες οι μονάδες πρέπει να είναι γνωστές στο στάδιο κατασκευής.
# Εγκαταστήστε το Hermes CLI αυτόνομα
npm install hermes-engine
# Μεταγλωττίστε JS σε bytecode HBC
npx hermesc -emit-binary -out bundle.hbc bundle.js
# Στατιστικά bytecode
npx hermesc -dump-bytecode bundle.hbc # shows HBC instructions
# Μέγεθος αρχικού JS vs HBC
wc -c bundle.js # 2,300,000 bytes
wc -c bundle.hbc # 1,450,000 bytes (37% reduction)
Η απόδοση του Hermes μετριέται με τρεις βασικές μετρικές: Time-To-Interactive (TTI), μέγεθος APK/IPA και κατανάλωση RAM. Σύμφωνα με τη Meta, στο Android το Hermes μειώνει το TTI κατά 34% σε σύγκριση με το JSC: από 4,2 δευτερόλεπτα σε 2,8 δευτερόλεπτα σε συσκευή μεσαίας κατηγορίας (Moto G7). Το μέγεθος APK μειώνεται κατά 28% χάρη στο συμπαγές bytecode και την απουσία βιβλιοθηκών JIT. Η κατανάλωση RAM είναι κατά μέσο όρο 22% χαμηλότερη στο ίδιο φορτίο — αυτό είναι ιδιαίτερα σημαντικό για συσκευές με 2-3 GB RAM. Στο iOS, το πλεονέκτημα είναι ακόμη μεγαλύτερο: δεδομένου ότι το JSC δεν μπορεί να χρησιμοποιήσει JIT, το Hermes παρέχει βελτίωση TTI έως 45%. Οι μετρικές βασίζονται σε δοκιμές της Meta με την εφαρμογή Facebook Lite. Σε πραγματικά έργα, το πλεονέκτημα ποικίλλει: για απλές οθόνες (λίστες, κείμενο) το Hermes δίνει μεγαλύτερη βελτίωση, για βαριές κινούμενες εικόνες — μικρότερη. Εργαλείο προφίλ: React Native Profiler + hermes profile --heap.
Hermes περιλαμβάνει ένα ενσωματωμένο εργαλείο προφίλ μνήμης, προσβάσιμο μέσω του Chrome DevTools. Συνδεθείτε στην εφαρμογή μέσω Metro, ανοίξτε την καρτέλα Memory και επιλέξτε Hermes (JavaScript) στους τύπους στιγμιότυπων. Το Hermes υποστηρίζει τρεις τύπους στιγμιότυπων: Heap Snapshot (όλα τα αντικείμενα), Allocation Timeline (διάρκεια ζωής αντικειμένων) και Allocation Sampling (επιλεκτικό προφίλ). Το Hades GC μειώνει τον αριθμό των παύσεων GC στο ελάχιστο — κατά μέσο όρο μία παύση 2-5ms ανά 10 δευτερόλεπτα εργασίας έναντι παύσεων 10-20ms στο JSC στην ίδια περίοδο.
Hades GC — είναι ο συλλέκτης σκουπιδιών στο Hermes, σχεδιασμένος για κινητά σενάρια με ελάχιστες παύσεις. Σε αντίθεση με το mark-sweep GC στο JSC, το Hades χρησιμοποιεί ταυτόχρονη (concurrent) συλλογή: ο συλλέκτης λειτουργεί παράλληλα με το κύριο νήμα εκτέλεσης, σταματώντας το μόνο για σύντομες περιόδους. Το Hades GC χωρίζει τον σωρό σε γενιές: η νεαρή γενιά (nursery) συλλέγεται συχνά και γρήγορα (Scavenge), η παλαιά γενιά συλλέγεται λιγότερο συχνά και με μικρότερες παύσεις. Το μέγεθος του σωρού είναι διαμορφώσιμο: προεπιλεγμένα — 2/3 της διαθέσιμης RAM της εφαρμογής, ελάχιστο όριο — 32 MB. Το Hades δεν χρησιμοποιεί προσέγγιση stop-the-world: ακόμη και η πλήρης συλλογή της παλαιάς γενιάς δεν διαρκεί περισσότερο από 5-8ms. Ο συλλέκτης είναι βελτιστοποιημένος για το τυπικό κινητό σενάριο: πολλά αντικείμενα μικρής διάρκειας ζωής (προσωρινές συμβολοσειρές, αντικείμενα React fibre), λίγα μακράς διάρκειας. Για εφαρμογές με εντατική δημιουργία αντικειμένων (λίστες, κινούμενες εικόνες) το Hades παρέχει πιο ομαλό FPS σε σύγκριση με το JSC.
Η ενεργοποίηση του Hermes εξαρτάται από την έκδοση του React Native και την πλατφόρμα. Από το React Native 0.70, το Hermes είναι ενεργοποιημένο από προεπιλογή για Android σε νέα έργα. Για iOS, το Hermes είναι προαιρετικό. Για ενεργοποίηση σε Android: στο αρχείο android/app/build.gradle ορίστε enableHermes: true στο μπλοκ project.ext.react.enableHermes. Για iOS: ορίστε το hermes_enabled σε true στο Podfile μέσω use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true). Μετά την ενεργοποίηση, εκτελέστε pod install. Για υπάρχοντα έργα, ελέγξτε τη συμβατότητα βιβλιοθηκών: το Hermes δεν υποστηρίζει Proxy, eval και ορισμένες λειτουργίες ES2021. Χρησιμοποιήστε npx react-native info για έλεγχο της διαμόρφωσης. Για εναλλαγή μεταξύ Hermes και JSC, αλλάξτε τη σημαία και εκτελέστε clean rebuild.
// android/app/build.gradle — ενεργοποιήστε το Hermes
project.ext.react = [
enableHermes: true,
cliPath: "node_modules/react-native/cli.js"
]
// iOS/Podfile — ενεργοποιήστε το Hermes στο 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
Οι κύριοι περιορισμοί του Hermes σχετίζονται με την εγκατάλειψη του JIT. Το Hermes δεν υποστηρίζει: Proxy και Reflect API (χρησιμοποιούνται σε MobX, Vue, ορισμένους διαχειριστές κατάστασης), BigInt (μεγάλοι αριθμοί), Symbol.toStringTag, WeakRef και FinalizationRegistry. Οι συναρτήσεις eval και new Function δημιουργούν εξαίρεση κατά την εκτέλεση. Οι回调 των μεθόδων Array.prototype.flat και flatMap με όρισμα this λειτουργούν με περιορισμούς. Οι μορφές ημερομηνίας ISO 8601 με ζώνες ώρας δεν επεξεργάζονται πλήρως. Οι περισσότεροι από αυτούς τους περιορισμούς δεν επηρεάζουν τυπικές εφαρμογές React Native: τα React και React Native χρησιμοποιούν περιορισμένο σύνολο λειτουργιών ES. Εάν μια βιβλιοθήκη απαιτεί Proxy (π.χ. MobX 6+ με Proxy), χρησιμοποιήστε configure({ useProxies: false }) ή επιλέξτε εναλλακτική. Για έλεγχο συμβατότητας υπάρχοντος κώδικα, εκτελέστε npx hermesc -check στο πακέτο σας — θα εμφανίσει τη λίστα των μη υποστηριζόμενων λειτουργιών.
Συχνές Ερωτήσεις
Στην κονσόλα της εφαρμογής εκτελέστε console.log(global.HermesInternal). Εάν το αντικείμενο HermesInternal υπάρχει — η εφαρμογή λειτουργεί σε Hermes. Εναλλακτικά: console.log(global.HermesInternal?.getRuntimeProperties()) — θα εμφανίσει την έκδοση της μηχανής και τις παραμέτρους GC. Σε εκδόσεις Release, το HermesInternal μπορεί να μην είναι διαθέσιμο για ελαχιστοποίηση μεγέθους.
Ελέγξτε τις ρυθμίσεις Podfile: το Hermes στο iOS απαιτεί New Architecture (Fabric Renderer). Ορίστε :hermes_enabled => true, εκτελέστε pod install --repo-update. Εάν το έργο ενημερώνεται από React Native κάτω από 0.70, ελέγξτε τη συμβατότητα βιβλιοθηκών με το New Architecture. Απενεργοποιήστε το Hermes εάν μια βιβλιοθήκη τρίτου μέρους απαιτεί JSC — για αυτό, αλλάξτε τη σημαία σε false και επανεγκαταστήστε τα Pods.
Όχι, το Hermes δεν επηρεάζει το Hot Reload / Fast Refresh. Κατά την ανάπτυξη, το Metro εκτελεί το πακέτο JavaScript χωρίς μεταγλώττιση Hermes (απλό JS). Το bytecode Hermes δημιουργείται μόνο για εκδόσεις Release. Στη λειτουργία Debug, χρησιμοποιείται το τυπικό JavaScriptCore ή το Hermes σε λειτουργία διερμηνείας. Η ταχύτητα του Hot Reload δεν αλλάζει όταν το Hermes είναι ενεργοποιημένο στη διαμόρφωση — η εναλλαγή γίνεται μόνο στο στάδιο παραγωγής κατασκευής.
Ναι, από το Expo SDK 45 το Hermes υποστηρίζεται για managed workflow. Στο app.json ορίστε "jsEngine": "hermes". Για bare workflow, το Hermes λειτουργεί όπως σε ένα κανονικό έργο React Native. Το Expo Go δεν υποστηρίζει Hermes — χρησιμοποιήστε Expo Dev Client ή EAS Build για εκδόσεις με Hermes. Ελέγξτε τη συμβατότητα βιβλιοθηκών μέσω του expo doctor.
Χρησιμοποιήστε το React Native Performance Monitor (μετρικές FPS) και το Hermes Profiling Tools. Δημιουργήστε δύο εκδόσεις της εφαρμογής — με Hermes και JSC — στην ίδια συσκευή. Μετρήστε: ψυχρή εκκίνηση (από το κλικ στο εικονίδιο έως την πρώτη διαδραστική οθόνη), TTI (Time-To-Interactive), μέγεθος APK/IPA και μέγιστη κατανάλωση RAM. Εκτελέστε τις δοκιμές τουλάχιστον 3 φορές για κάθε διαμόρφωση. Τυπικό πλεονέκτημα Hermes: εκκίνηση 20-40% ταχύτερη, RAM 15-25% λιγότερη.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης