MWAN MOBILE

×
mwan_logo
blog-banner

What makes Hermes engine (React Native) fast?

Miscellaneous 28-Sep-2022

Brief about Hermes

Hermes is a new javascript engine optimised for react-native — introduced in 2020 by Facebook.

Historically, React Native was using JavaScriptCore (JS engine) as default for running Javascript code.

In near future, we will see Hermes as the default JS engine for react-native.

If you have already heard about Hermes — it speeds up app launch, reduces app size, and many more. In this blog, we will see how Hermes achieves all of the above and some of the other interesting features it provides.

Before we delve into the actual mechanism, we have to be familiar with the few basic terms.

Basic terms

  1. Babel: Babel is a free and open-source JavaScript trans-compiler. React Native uses Babel to convert React syntax and the newer ES5+ syntax into code, that can be run in a JavaScript environment that doesn’t support those features. This step is called transpilation.
  2. Minification: In addition to above, for production, the React Native server reduces the size of your JavaScript file by removing unnecessary whitespace, shortening variable names, removing unused code, and performing other optimizations.
  3. Parse: Converts the source code into compilers known code. eg: Javascript is function-oriented, but it will also support classes, in the background classes are converted into functions
  4. Compile Converts JS code into byte-code.
  5. Execute: Executing the byte-code, means
  6. Build time: also called compiled time, it converts source code into executable code, which is byte code.
  7. Run time: Executes the code.

Mechanism without and with Hermes

Without Hermes

The build time process has only Babel and Minify steps, and Runtime has Parse, compile and execution.

Without Hermes

With Hermes

The only Execution process was there in the Run-time process, remaining all were brought to build time.

With Hermes

In summary, Hermes will send a precompiled optimised byte code instead of plain javascript source so it reduces startup time, decrease TTI by nearly half, and does much more!

Inaddition, Hermes will also well manage Garbage collection
— A regular JS engine has “Stop the world” to perform Garbage collection

Generally, it uses GenGC. Generational Garbage collector, was the previous default GC for Hermes and single-threaded, having long GC pauses because it works in the Main JS thread. Some observations from Facebook, it has a pause of 200ms average or 1.4sec at P99, some times 7sec. The old generation uses a mark-compact strategy. The new generation uses a typical semi-space copying strategy to make it good at aggressively returning memory to OS.

To Overcome these shortcomings in GenGC, they implemented Concurrent GC named Hades.

To Overcome these shortcomings in GenGC, they implemented Concurrent GC named Hades.

Hades GC — it is default Hermes GC, is to overcome problems in GenGC. It works in the background thread concurrently with the interpreter running JS code. Its main principle is to achieve those low pause times. It uses the Mark-Sweep Collector strategy.

You can check which Garbage collector is enabled — HermesInternal.getRuntimeProperties().GC

Incase you don’t have this, No problem use following snippet to get Hades

  • -DHERMESVM_GCKIND = HADES to request Hades
  • And NONCONTIG_GENERATIONAL to request GenGC

These are one of the main reasons to achieve benefits with Hermes. Also there are many other improvements in Hermes, we try to add them early

Enable Hermes in your React Native app

Official documentation is available at: https://reactnative.dev/docs/hermes

Android

Edit your android/app/build.gradle file and make the change illustrated below:

project.ext.react = [
entryFile: "index.js",
- enableHermes: false // clean and rebuild if changing
+ enableHermes: true // clean and rebuild if changing
]

Also, if you’re using ProGuard, you will need to add these rules in proguard-rules.pro

-keep class com.facebook.hermes.unicode.** { *; }
-keep class com.facebook.jni.** { *; }

Next, if you’ve already built your app at least once, clean the build:

$ cd android && ./gradlew clean

That’s it! You should now be able to develop and deploy your app as usual:

$ npx react-native run-android

iOS

Since React Native 0.64, Hermes also runs on iOS. To enable Hermes for iOS, edit your ios/Podfile file and make the change illustrated below:

use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
- :hermes_enabled => false
+ :hermes_enabled => true
)

Next, install the Hermes pods:

$ cd ios && pod install

That’s it! You should now be able to develop and deploy your app as usual:

$ npx react-native run-ios

Source: Medium