DEV Community

Cover image for React Native: What You Need To Know About Hermes.
OGcodes
OGcodes

Posted on • Edited on

React Native: What You Need To Know About Hermes.

TL;DR:

Hermes is an open-source lightweight JavaScript engine optimized for React Native built by Facebook, It improves performance by decreasing memory utilization, reduces download size, and decreases TTI (Time To Interaction).

Prerequisites

  • If you are new to React Native and want to get started, here is a good resource you will find helpful.
  • For Windows users, make sure you have Microsoft Visual C++ 2015 Redistributable installed, you can check if it is installed by searching for “Microsoft Visual C++ 2015 Redistributable” after pressing the Windows key. Microsoft Visual

Introduction

On the 11th of July 2019, At Chain React 2019, Hermes JavaScript engine was announced running on React Native, It was first used internally by Facebook before it went open source. Before this, the React Native team at Facebook analyzed performance data and noticed that the JavaScript engine itself was a significant factor in start-up time and download size.

Why you should use Hermes

We built a new JavaScript engine we call Hermes. It is
designed to improve app performance, focusing on our
React Native apps, even on mass-market devices with
limited memory, slow storage, and reduced computing
power.

  • Facebook Team

hermes used

The three main architecture Facebook focus on improving are :

  1. Adapting garbage collection to mobile OSes constraints.
  2. Ditching the JIT (just-in-time) compiler.
  3. Precompiling the JavaScript source code.

Adapting garbage collection came with many reasons

Hermes adapting garbage collection aids to reduce the overall virtual memory consumption by implementing on-demand allocation in non-contiguous chunks that can be moved around and returned to the OS when no longer needed, Operating systems aggressively kill applications that use too much memory. When apps are killed, slow restarts are required and background functionality suffers.

The following are the features of the garbage collector :

  • On-demand allocation: Allocates VA (virtual address) space in chunks only as needed.
  • Noncontiguous: VA (virtual address) space need not be in a single memory range, which avoids resource limits on 32-bit devices.
  • Moving: Being able to move objects means the memory can be defragmented and chunks that are no longer needed are returned to the operating system.
  • Generational: Not scanning the entire JavaScript heap reduces time.

Why ditching the JIT compiler helps

  • A JIT compiler warm-up when an application starts, they have issues improving TTI and may even hurt TTI more by increasing it.
  • A JIT compiler adds to native code size and memory consumption, which negatively affects primary metrics.
  • A JIT compiler is likely to hurt the metrics we care about most, so Facebook chose not to implement it. Instead of focusing on interpreter performance as the right trade-off for Hermes.

Precompiling the JavaScript source code into bytecode helps.

  • Parsing and compilation directly reduce the time spent on any tasks at launch time.
  • Since the precompilation phase has more relaxed time constraints, bytecode generated is usually smaller and more efficient, this aids the compiler to apply whole-program optimizations such as function deduplication and string table packing.
  • Hermes bytecode can be mapped into memory without requiring to read the whole file in advance, which brings a huge improvement with slow flash memories and reduces the chances of an app being killed by the OS due to excessive memory usage which was an issue before now in React Native.
  • Hermes tries to be efficient through bytecode precompilation — rather than loading JavaScript and then parsing it. Hermes employs ahead-of-time (AOT) compilation during the mobile app build process to allow for more extensive bytecode optimization. Similar to the Fuchsia Dart compiler for iOS which is also an AOT compiler.

Bytecode precompilation with Hermes

Hermes for iOS

Before version 0.64, Hermes did not have support for iOS and that is because Apple is forced to use JavaScriptCore and not V8 like Android devices.

JavaScriptCore is an optimizing virtual machine and it’s the built-in engine for Webkit.

WebKit is a browser engine used in the Safari web browser and every other iOS browser, it was built by Apple in C++ and runs on macOS, iOS, and Linux.

Fun-Fact: This engine was used by BlackBerry.

On the other hand, V8 is an open-source WebAssembly and JavaScript engine, it was built by Google in C++ also. V8 is used in Node.js and it runs on Chrome, Chromium, and lately, it is what powers the Microsoft Edge browser.

V8 implements WebAssembly and ECMAScript, and runs on Windows, macOS, and Linux.

Hermes opt-in on iOS

It’s 2021🎊🎊 and with the release of version 0.64 we are happy to now use Hermes to build on iOS as well. To enable Hermes on iOS, set hermes_enabled to true in your Podfile and run pod install.

Hermes with Proxy Support

We now have Proxy support to Hermes, enabling compatibility with popular community projects like react-native-firebase and mobx. If you have been using these packages you can now migrate to Hermes for your project.

Hermes for Android

Setting up Hermes is seamless and easy.
According to React Native’s awesome documentation, we will first start by editing our android/app/build.gradle file and setting enableHermes to true like so :

If we use ProGuard in our application, we will have to add rules in android/app/proguard-rules.pro like so :

For these changes to take effect we will need to clean build, so in our terminal, we will do like so :

$ cd android && ./gradlew clean

Finally, we are ready to build and test our app and we will do like so :

$ npx react-native run-android

Confirming if Hermes is enabled in our project

If we created a new app with $ npx react-native init AppName before setting up Hermes we will see that Hermes is enabled at the top-right corner of our app screen.

hermes app

But if we had an existing project we can still test by making use of the global HermesInternal variable like so :

To see full benefits why we use Hermes, you can build a release version of your app to compare the differences and see improvements in app startup time and bundle size like so :

$ npx react-native run-android --variant release

Conclusion

In this article we have an understanding of the following things :

  1. We now have Hermes Support for both Android and iOS.
  2. Difference between Interpretation with React Native conventional engine and Bytecode precompilation with Hermes.
  3. What Hermes does under the hood.

I will like to thank Tzvetan Mikov, Will Holen, and the rest of the Hermes team on their work to making Hermes a success.

Thanks for reading

With Love

I hope this was helpful, don’t forget to like and share this article, you can tweet at @Godswillokokon if you have any questions or drop a comment below.

Top comments (2)

Collapse
 
stevepepple profile image
Steve Pepple

This article is super clear and helpful, thank you!

We're trying to enable this option for our Android version (see app here Vibemap for iOS and Android), but for some reason the code isn't properly compiling to bytecode when hermes is enabled, which results in slow performance. Is this an issue you're familiar with or any ideas how we might fix that. Any ideas would be tremendously helpful!

Collapse
 
ibelgin profile image
Belgin

Is there a way to disable Hermes in iOS. I am having some issues integrating it with other modules. I tried several ways to remove it but nothing seems to work.