
안녕하세요오~~~😆😆 오랜만에 포스팅으로 찾아뵙습니다...! 😅
지난 시간에는 새로운 아키텍처의 구성요소 중 하나인 JSI를 배웠습니다. 제 개인적인 생각으로는 JSI가 새로운 아키텍처의 🌸(꽃)이라고 생각합니다. 그래서 내용도 다소 길었습니다. 😅
오늘은 새로운 아키텍처의 다른 구성요소인, JavaScript 엔진 Hermes에 대해 알아보도록 하겠습니다!! +_+
기존 React Native는 JSC(JavaScriptCore)를 기본 JavaScript 엔진으로 사용해 왔습니다. 이 구조에서는 앱 실행 시점에 JavaScript 코드가 해석되고 네이티브 모듈이 초기화되기 때문에, 메모리 사용량이 증가하고 초기 로딩 성능에 한계가 있었습니다. React Native 0.64에서는 위 성능 개선을 목표로 한 새로운 JavaScript 엔진인 Hermes가 도입되었습니다. Hermes가 도입된 이후, React Native 개발자 커뮤니티에서 성능 향상 측면에 대해 큰 지지를 받았습니다.
새로운 아키텍처의 흐름에 의하면 Hermes는 앱 빌드 타임에 실행되는 주요 구성 요소 중 하나입니다.
기존 JSC 엔진은 런타임에 JavaScript 코드를 실행할 때, "파싱 → 컴파일"하는 과정이 필요했습니다. 이로인해 앱 시작 시 JavaScript 실행 준비 과정에서 지연이 생겨 초기 로딩 성능에 한계가 있었습니다.
이를 해결하기 위해 Hermes는 빌드 타임에 JavaScript 소스 코드를 미리 바이트 코드로 변환합니다. 바이트 코드 파일은 Hermes가 해석하거나 다시 컴파일할 필요 없이 직접 실행할 수 있는 더 간단하고 효율적인 코드 형식입니다. 이 바이트코드는 런타임에 훨씬 더 빠르게 로드될 수 있어, 애플리케이션의 시작 시간을 단축시킵니다.
바이트 코드: 고급 언어로 작성된 소스 코드를 가상머신이 이해할 수 있도록 변환한 중간 코드
빌드 타임에는... Codegen도 열심히 네이티브 모듈을 생성한다는 사실...!
잊지 않으셨죠??! 😆
앱을 실행하면 미리 생성된 바이트 코드 파일을 로드하는 것부터 시작합니다. 앞서 설명한 것처럼 Hermes는 빌드 타임에 이미 소스 코드를 파싱하고 컴파일해두었기 때문에, 앱 시작 속도가 훨씬 빨라집니다.
Hermes는 이전 시간에 배운 JSI를 사용해 브릿지를 사용하지 않고 네이티브 함수와 객체에 직접 접근 할 수 있습니다. 주로 API를 통해 데이터를 가져오거나 상태를 업데이트하고, 사용자 입력에 응답하는 등 앱의 로직과 데이터, 이벤트 처리를 담당합니다. 또한, 새로운 렌더링 시스템인 Fabric을 사용하여 UI를 업데이트 할 수 있습니다.
(Fabric에 대한 자세한 내용은 다다음 시간에 살펴보겠습니다! 🤩)
Hermes는 앱 시작 속도 뿐만 아니라 앱 번들 크기와 메모리 사용량도 최적화합니다. Meta에서는 JSC와 Hermes를 직접 비교했으며, 이 벤치마킹 데이터를 바탕으로 Hermes의 장점을 소개하겠습니다!
TTI(Time to Interactive)는 앱이 실행된 시점부터 사용자가 앱과 상호 작용할 수 있는 시점까지의 시간입니다.
런타임에 JavaScript를 파싱하고 해석하는 것은 느리고 리소스를 많이 소모합니다. Hermes는 빌드 단계에서 JavaScript를 바이트코드로 사전 컴파일하기 때문에 TTI를 단축시켜 원활한 사용자 경험을 제공합니다.
메모리 사용량은 앱을 실행할 때 사용되는 메모리 크기입니다.
Hermes 엔진은 모든 코드를 빌드타임에 컴파일한 뒤, 런타임에는 메모리에 저장된 코드를 실행시키기만 하면 되기 때문에, 런타임에 활발하게 컴파일러가 돌아가며, 수시로 메모리 읽고 쓰기를 반복하는 JSC 대비 메모리 사용량이 더 적습니다. 또한 Hermes 엔진에서는 새로운 가비지 컬렉터인 Hades가 적용되었는데, 앱의 원활한 구동에 실제로 필요한 메모리만을 사용하도록 하여 메모리 사용량을 최적화 되었습니다.
바이너리 크기는 APK(안드로이드) 또는 IPA(iOS) 파일에 포함된 React Native 애플리케이션의 크기입니다.
압축된 javascript code보다 압축된 byte code의 사이즈가 약간 더 크긴하지만 hermes의 native code size는 기존 javascriptCore engine size보다 작아졌기 때문에 전체 앱 사이즈는 더 작아진다고 합니다.
(😎: 다만 이는 js engine을 앱 번들에 포함시키는 android 한정이고, javascriptCore를 포함할 필요 없었던 ios입장에서는 오히려 앱 사이즈가 약간 더 커진다고 합니다.)
Hermes는 결국...
- 빌드 타임에 JS 코드를 바이트코드로 사전 컴파일을 하여,
- 런타임에 앱 시작 속도 단축과 바이너리 크기를 감소시켜 JSC를 보완할 수 있게 되었습니다! 👏👏!!
그러니 Hermes 비싸도 뭐라 하지 않긔...!⭐️
다음 포스팅에서는 새로운 아키텍처의 다른 구성 요소인 Turbo Module에 대해 알아보겠습니다!
그럼 다음 포스팅에서 만나요~~ 🥹👋
참고
https://reactnative.dev/blog/2022/07/08/hermes-as-the-default#benchmarking
https://medium.com/crossplatformkorea/hermes-%EC%97%94%EC%A7%84%EC%9D%B4%EB%9E%80-cbeb953e0f10