According To Facebook:
How Hermes improves React Native performance
- The time it takes for the app to become usable, called time to interact (TTI)
- The download size (on Android, APK size)
- Memory utilization
Key Hermes architectural decisions
Mobile device limitations, such as smaller amounts of RAM and slower flash, led us to make certain architectural decisions. To optimize for this environment, we implemented the following:
The bytecode is designed so that at runtime, it can be mapped into memory and interpreted without needing to eagerly read the entire file. Flash memory I/O adds significant latency on many medium and low-end mobile devices, so loading bytecode from flash only when needed and optimizing bytecode for size leads to significant TTI improvements. In addition, because the memory is mapped read-only and backed by a file, mobile operating systems that don’t swap, such as Android, can still evict these pages under memory pressure. This reduces out-of-memory process kills on memory constrained devices.
Hermes today has no JIT compiler. This means that Hermes underperforms some benchmarks, especially those that depend on CPU performance. This was an intentional choice: These benchmarks are generally not representative of mobile application workloads. We have done some experimentation with JITs, but we believe that it would be quite challenging to achieve beneficial speed improvements without regressing our primary metrics. Because JITs must warm up when an application starts, they have trouble improving TTI and may even hurt TTI. Also, a JIT adds to native code size and memory consumption, which negatively affects our primary metrics. A JIT is likely to hurt the metrics we care about most, so we chose not to implement a JIT. Instead, we focused on interpreter performance as the right trade-off for Hermes.
Garbage collector strategy
On mobile devices, efficient use of memory is especially important. Lower-end devices have limited memory, OS swapping does not generally exist, and operating systems aggressively kill applications that use too much memory. When apps are killed, slow restarts are required and background functionality suffers. In early testing, we learned that virtual address (VA) space, especially contiguous VA space, can be a limited resource in large applications on 32-bit devices even with lazy allocation of physical pages.
To minimize memory and VA space used by the engine, we have built a garbage collector with the following features:
- On-demand allocation: Allocates VA space in chunks only as needed.
- Noncontiguous: VA space need not be in a single memory range, which avoids resource limits on 32-bit devices.
- Moving: Being able to move objects means memory can be defragmented and chunks that are no longer needed are returned to the operating system.
How To Migrate and Start using Hermes Engine:
First, ensure you’re using at least version 0.60.2 of React Native. If you’re upgrading an existing app ensure everything works before trying to switch to Hermes.
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 ]
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 normal:
$ react-native run-android
Confirming Hermes is in use
If you’ve just created a new app from scratch you should see if Hermes is enabled in the welcome view:
const isHermes = () => global.HermesInternal != null;
To see the benefits of Hermes, try making a release build/deployment of your app to compare. For example:
$ react-native run-android --variant release
At the end, I will Show you a comparision between Hermes Engine & V8