Hermes เป็นเอนจิน JavaScript โอเพนซอร์สที่พัฒนาขึ้นเฉพาะสำหรับ React Native และปรับแต่งสำหรับอุปกรณ์มือถือ ซึ่งแตกต่างจาก JavaScriptCore, Hermes คอมไพล์โค้ด JS ล่วงหน้าเป็นไบต์โค้ดในระหว่างขั้นตอนการ build ทำให้แอปพลิเคชันเริ่มต้นได้อย่างรวดเร็ว ตามข้อมูลจาก Meta, Hermes Docs, 2024, Hermes ถูกใช้เป็นค่าเริ่มต้นใน React Native ตั้งแต่เวอร์ชัน 0.70
ประเด็นสำคัญ
Hermes เป็นเอนจิน JavaScript ขนาดกะทัดรัดที่สร้างโดยทีม Meta สำหรับ React Native โดยเฉพาะ เปิดตัวในปี 2019 เพื่อเป็นทางเลือกแทน JavaScriptCore (JSC) ซึ่งถูกใช้เป็นค่าเริ่มต้นใน React Native เป้าหมายหลักของ Hermes คือการให้การเริ่มต้นที่เร็วที่สุดเท่าที่เป็นไปได้สำหรับแอปพลิเคชันมือถือ โดยเฉพาะบน Android ที่มีทรัพยากรจำกัด
คุณสมบัติหลักของ Hermes คือ การคอมไพล์ล่วงหน้า (AOT — Ahead-of-Time) ซึ่งแตกต่างจากเอนจิน JS แบบดั้งเดิมที่คอมไพล์โค้ดในระหว่างการทำงาน (JIT — Just-in-Time), Hermes จะคอมไพล์ JavaScript เป็นไบต์โค้ดในระหว่างขั้นตอนการ build แอป ซึ่งหมายความว่าไม่มีการคอมไพล์เกิดขึ้นบนอุปกรณ์ — ไบต์โค้ดจะถูกดำเนินการทันทีโดยเครื่องเสมือนของ Hermes
Hermes ไม่ใช่เอนจิน JS สากล — มันถูกปรับแต่งเฉพาะสำหรับสถานการณ์ React Native เท่านั้น มันขาดคุณสมบัติที่ไม่จำเป็นในการพัฒนามือถือ: eval, generators และคุณสมบัติ ES6 บางอย่าง สิ่งนี้ช่วยให้เอนจินมีขนาดกะทัดรัดและเร็วขึ้น ตามข้อมูลของ Meta ขนาดของ Hermes เมื่อบีบอัดอยู่ที่ประมาณ 200–300 KB ซึ่งเล็กกว่า JSC (ประมาณ 2–3 MB) อย่างมีนัยสำคัญ
สถาปัตยกรรมของ Hermes แตกต่างจากเอนจิน JS แบบดั้งเดิมตรงที่ไม่มี JIT คอมไพเลอร์ แต่ Hermes ใช้เครื่องเสมือน (VM) ที่มีประสิทธิภาพซึ่งดำเนินการไบต์โค้ดที่คอมไพล์ไว้ล่วงหน้า การละทิ้ง JIT ให้ข้อได้เปรียบหลักสามประการ: ประสิทธิภาพที่คาดเดาได้, การใช้หน่วยความจำที่ลดลง และเวลาเริ่มต้นที่สั้นลง
ไบต์โค้ดของ Hermes เป็นการแสดงโค้ด JavaScript แบบกะทัดรัดที่ปรับแต่งสำหรับการดำเนินการที่รวดเร็ว ในระหว่างขั้นตอนการ build (ผ่าน Metro), ไฟล์ JavaScript จะถูกคอมไพล์เป็นไฟล์ .hbc (Hermes Bytecode) แอปโหลดไฟล์เหล่านี้ และ VM Hermes ดำเนินการโดยไม่ต้องคอมไพล์เพิ่มเติม กระบวนการ build ถูกรวมเข้ากับ Metro ผ่านปลั๊กอิน hermes-transformer
ขั้นตอนการประมวลผล JavaScript ใน Hermes ประกอบด้วยสามขั้นตอน: Parse — การวิเคราะห์ไวยากรณ์ของซอร์สโค้ด, Compile — การแปลเป็นไบต์โค้ด, Execute — การดำเนินการไบต์โค้ดโดยเครื่องเสมือน สองขั้นตอนแรกทำงานในระหว่างขั้นตอนการ build ขั้นตอนที่สามทำงานบนอุปกรณ์ สิ่งนี้แตกต่างโดยพื้นฐานจาก JSC ซึ่งทั้งสามขั้นตอนทำงานบนอุปกรณ์
# การคอมไพล์ไบต์โค้ด Hermes ระหว่าง build
hermes -emit-binary -out index.hbc index.js
# ตรวจสอบขนาดไบต์โค้ดที่สร้าง
ls -lh index.hbc
# แสดงสถิติไบต์โค้ด
hermes -dump-bytecode index.hbc
# ปรับแต่งไบต์โค้ดสำหรับโปรดักชัน
hermes -O index.js -emit-binary -O target.hbc
หลังจากคอมไพล์ ไฟล์ .hbc ทั้งหมดจะถูกบรรจุลงใน APK หรือ IPA พร้อมกับโค้ดเนทีฟ เมื่อแอปเริ่มต้น VM Hermes จะโหลดไบต์โค้ดและเริ่มดำเนินการเกือบจะทันที — ไม่จำเป็นต้องใช้เวลา预热 JIT ซึ่งเป็นเรื่องปกติสำหรับ V8 และ JSC
การเปรียบเทียบ Hermes และ JavaScriptCore (JSC) ช่วยให้เข้าใจว่าเมื่อใดควรเลือกเอนจินใด JSC เป็นเอนจิน JS เต็มรูปแบบจาก Apple ใช้ใน Safari Hermes เป็นเอนจินเฉพาะสำหรับ React Native การเลือกระหว่างพวกเขาขึ้นอยู่กับลำดับความสำคัญของโปรเจกต์
| คุณลักษณะ | Hermes | JavaScriptCore |
|---|---|---|
| การคอมไพล์ | AOT (ระหว่าง build) | JIT (บนอุปกรณ์) |
| เวลาเริ่มต้น | 50–100 ms | 200–400 ms |
| การใช้หน่วยความจำ | น้อยกว่า 30–40% | ระดับพื้นฐาน |
| ขนาด | ~250 KB (บีบอัด) | ~2 MB (บีบอัด) |
| รองรับ ES6+ | จำกัด | เต็มรูปแบบ |
Hermes ชนะในด้านความเร็วเริ่มต้นและการใช้หน่วยความจำ แต่ด้อยกว่า JSC ในประสิทธิภาพการคำนวณที่ซับซ้อน JIT คอมไพล์ของ JSC ปรับแต่งเส้นทางโค้ดร้อนในระหว่างการดำเนินการ ทำให้ได้เปรียบในการทำงานที่ใช้ CPU สูง สำหรับแอป React Native ทั่วไป ซึ่งการอัปเดต UI และการนำทางเป็นภาระงานหลัก Hermes มอบประสบการณ์ผู้ใช้ที่ดีกว่าด้วยการเริ่มต้นที่รวดเร็ว
Hermes รวมการปรับแต่งหลายอย่างที่เฉพาะสำหรับ React Native ที่สำคัญที่สุดคือการรวมเข้ากับ JSI (JavaScript Interface) Hermes รองรับ JSI โดยตรง ทำให้สามารถใช้สถาปัตยกรรม React Native ใหม่ (Fabric + Turbo Modules) โดยไม่มีเลเยอร์เพิ่มเติม สิ่งนี้ทำให้ Hermes และสถาปัตยกรรมใหม่เป็นคู่ที่เหมาะสมที่สุดสำหรับประสิทธิภาพสูงสุด
Hermes ใช้ garbage collector แบบเจเนอเรชัน (generational GC) ที่ปรับแต่งสำหรับอุปกรณ์มือถือ ซึ่งแตกต่างจาก JSC ที่การเก็บขยะอาจทำให้เกิดการหยุดชะงักใน UI (jank) ที่สังเกตได้ Hermes ดำเนินการ GC เป็นส่วนเล็ก ๆ ระหว่างเฟรม ลดผลกระทบต่อประสบการณ์ผู้ใช้ ตามข้อมูลของ Meta การหยุด GC ใน Hermes นั้นสั้นกว่าใน JSC 2–3 เท่าในสถานการณ์ React Native ทั่วไป
Hermes รองรับการโหลดโมดูลแบบ lazy — โมดูล JavaScript จะถูกคอมไพล์เมื่อจำเป็นจริง ๆ เท่านั้น สิ่งนี้ลดขนาดไบต์โค้ดและเร่งการเริ่มต้น นอกจากนี้ Hermes ยังประเมินนิพจน์คงที่ในเวลาคอมไพล์ แทนที่การเรียกใช้ฟังก์ชันด้วยค่าคงที่เมื่อเป็นไปได้
// ตัวอย่างการปรับแต่งเฉพาะของ Hermes
// 1. Hermes แทรกนิพจน์คงที่แบบอินไลน์
const TAX_RATE = 0.07;
const price = 100;
// Hermes คำนวณล่วงหน้า: TAX_RATE * price ระหว่างการคอมไพล์
const totalWithTax = price * (1 + TAX_RATE);
// 2. Hermes ปรับแต่งลูกโซ่การเข้าถึงคุณสมบัติ
const config = { api: { timeout: 5000 } };
// Hermes แคชการเข้าถึง config.api ภายใน
const timeout = config.api.timeout;
fetch(url, { timeout });
สิ่งสำคัญที่ควรทราบคือ Hermes รองรับ การดีบักผ่าน Chrome DevTools (ตั้งแต่ Hermes 0.12) นักพัฒนาสามารถใช้เครื่องมือที่คุ้นเคย: เบรกพอยต์, การโปรไฟล์หน่วยความจำ, การตรวจสอบตัวแปร สิ่งนี้ขจัดข้อโต้แย้งหลักประการหนึ่งต่อ Hermes ในเวอร์ชันแรก ๆ ซึ่งการดีบักมีจำกัด
การตั้งค่า Hermes ขึ้นอยู่กับเวอร์ชันของ React Native ตั้งแต่ React Native 0.70, Hermes ถูกเปิดใช้งานเป็นค่าเริ่มต้นสำหรับโปรเจกต์ใหม่ สำหรับโปรเจกต์ที่สร้างก่อนหน้านี้ หรือเมื่อเปลี่ยนเอนจิน การกำหนดค่าจะทำผ่านการตั้งค่า build
สำหรับ Android, Hermes ถูกเปิดใช้งานในไฟล์ android/app/build.gradle ผ่านแฟล็ก hermesEnabled สำหรับ iOS, การกำหนดค่าจะทำใน Podfile ผ่านตัวแปร :hermes_enabled หลังจากเปลี่ยนการกำหนดค่า คุณต้องติดตั้ง pods ใหม่และ build โปรเจกต์ใหม่
// android/app/build.gradle — เปิดใช้งาน Hermes
project.ext.react = [
enableHermes: true
]
// iOS Podfile — เปิดใช้งาน Hermes
hermes_enabled = true
pod 'hermes-engine'
เพื่อตรวจสอบว่า Hermes กำลังทำงานในแอปของคุณ ให้รัน adb logcat | grep Hermes บน Android หรือตรวจสอบคอนโซล Xcode บน iOS เมื่อแอปเริ่มต้น Hermes จะแสดงข้อความเช่น “Hermes VM initialized” หรือใกล้เคียง คุณยังสามารถตรวจสอบ globalThis.HermesInternal ในโค้ด JavaScript — ถ้า Hermes ทำงานอยู่ คุณสมบัตินี้จะพร้อมใช้งาน
// ตรวจสอบว่า Hermes ทำงานอยู่หรือไม่
if (typeof globalThis.HermesInternal !== 'undefined') {
console.log('✅ เอนจิน Hermes ทำงานอยู่');
console.log(
'เวอร์ชัน:',
globalThis.HermesInternal.getEngineProperties()
);
} else {
console.log('❌ Hermes ไม่ทำงาน (fallback เป็น JSC)');
}
คำถามที่พบบ่อย
ใช่, Hermes เข้ากันได้อย่างสมบูรณ์กับสถาปัตยกรรม React Native ใหม่ (Fabric + Turbo Modules) ยิ่งไปกว่านั้น Hermes และ JSI ถูกพัฒนาร่วมกันและให้ประสิทธิภาพที่ดีที่สุดเมื่อใช้เป็นคู่
ใช่, Hermes รองรับทั้งสองแพลตฟอร์ม — iOS และ Android บน iOS, Hermes แทนที่ JavaScriptCore มาตรฐาน ให้ข้อดีเดียวกัน: เริ่มต้นเร็วและการใช้หน่วยความจำน้อยลง
Hermes รองรับคุณสมบัติ ES6+ ส่วนใหญ่แต่มีข้อจำกัด: eval, generators และ Proxy ไม่พร้อมใช้งาน ขอแนะนำให้ใช้ Babel transpilation เพื่อความเข้ากันได้ เช่นเดียวกับ React Native ทั่วไป
Hermes ลดขนาดแอปด้วยไบต์โค้ดที่กะทัดรัดและขนาดเอนจินที่เล็กกว่า ไบต์โค้ดโดยทั่วไปจะมีขนาดกะทัดรัดกว่าโค้ด JS ที่เทียบเท่า 20–30% และตัวเอนจินเองมีน้ำหนัก ~250 KB เทียบกับ ~2 MB ของ JSC
ไลบรารีส่วนใหญ่เข้ากันได้กับ Hermes ถ้าไลบรารีใช้ eval, Proxy หรือคุณสมบัติที่ไม่ได้มาตรฐาน — ให้ตรวจสอบว่ามีเวอร์ชันที่เข้ากันได้กับ Hermes หรือไม่ คุณยังสามารถใช้ปลั๊กอิน Babel เพื่อแทนที่โครงสร้างที่ไม่รองรับ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม