JavaScript Achieves Breakthrough Performance with Static Hermes

Elves Vieira
7 min readDec 20, 2023

--

In an era where performance is paramount, JavaScript’s dynamic nature presents both a boon and a bane. The language’s ubiquity across web and mobile platforms is unmatched, but when it comes to raw computational speed and efficiency, developers often find themselves longing for the performance typically reserved for statically-typed, compiled languages. This is where Static Hermes enters the fray, promising a new chapter in JavaScript’s evolution. By infusing static typing into the mix, Static Hermes aims to elevate JavaScript’s performance to rival that of native applications, all while maintaining the language’s inherent flexibility and ease of use. With this innovative approach, the horizon of JavaScript’s capabilities is poised to expand dramatically, opening up a realm of possibilities for high-performance applications.

The Pain Points of JavaScript Performance

JavaScript’s dynamic typing system is a double-edged sword. On one hand, it offers developers the flexibility to write code quickly and concisely, but on the other, it introduces a layer of unpredictability that modern JavaScript engines struggle to optimize. This unpredictability stems from not knowing the data types of variables until runtime, which means engines must constantly make educated guesses about the types — a process known as speculative optimization.

While Just-In-Time (JIT) compilers have made strides in improving JavaScript performance, they can only optimize code to a certain extent. JIT involves monitoring the code’s execution and identifying “hot spots” to compile to native code on the fly. However, if a variable’s type changes unexpectedly — a common occurrence in JavaScript — the JIT compiler must deoptimize and recompile the code, often at critical times during execution. This results in a performance penalty and hinders the ability of JavaScript applications to achieve consistent high-speed performance.

Furthermore, the garbage-collected nature of JavaScript adds another layer of performance unpredictability. Memory management is abstracted away from the developer, leading to potential inefficiencies and pauses during garbage collection cycles. This can be particularly problematic for applications requiring real-time responsiveness, such as gaming or interactive animations.

The consequence of this unpredictability is that developers often resort to manual optimizations, like type hinting or avoiding certain language features, to coax the JIT compiler into generating more efficient code. These practices, while sometimes effective, can lead to code that is less readable and more difficult to maintain. They also represent a departure from the scripting language’s ethos of ease and speed of development.

In essence, the dynamic nature of JavaScript, while instrumental in its widespread adoption and versatility, introduces significant performance challenges that require complex workarounds, often limiting the language’s potential in high-performance computing contexts. Static Hermes proposes a solution that seeks to retain JavaScript’s developer-friendly attributes while substantially mitigating these performance pain points.

The Hermes Engine

The Hermes engine is Meta’s brainchild, crafted specifically to cater to the unique demands of React Native applications. Recognizing the need for faster app start times and more efficient memory usage, Meta designed Hermes as an open-source JavaScript engine optimized for running on mobile devices. At its core, Hermes employs Ahead-Of-Time (AOT) compilation to transform JavaScript into bytecode before the application is ever run. This means that when a React Native application is launched, the Hermes engine can execute pre-compiled bytecode, significantly reducing start-up time.

The AOT approach contrasts sharply with the traditional Just-In-Time (JIT) compilation strategies used by many other JavaScript engines, which compile code at runtime. While JIT can optimize code execution, it often does so at the cost of slower application start times and increased memory use — two critical issues in mobile environments where resources are at a premium.

by https://engineering.fb.com/author/marc-horowitz/

Hermes’ bytecode is also designed to be compact, reducing the size of the application and the amount of code that needs to be parsed when the app starts. This has a direct, positive impact on the performance metrics that matter most to users: how quickly an app loads and how smoothly it runs.

Furthermore, Hermes comes with a highly-efficient garbage collector tailored for low-memory usage. This helps alleviate the impact of JavaScript’s garbage-collected nature on mobile applications, where interruptions or delays can significantly degrade the user experience.

Static Hermes: A New Hope

While the Hermes engine has adeptly tackled the challenges of mobile app startup times and efficiency, the inherent unpredictability of JavaScript’s compilation remained a complex issue. Traditional AOT compilation provided a partial remedy but left the door open for an even more refined solution. Enter Static Hermes, the evolution of the Hermes engine that takes performance optimization to the next level.

Static Hermes introduces a revolutionary optional AOT compilation to native code, targeting the imprevisibility that plagues JavaScript performance. By leveraging static typing, Static Hermes substantially reduces the guesswork involved in the JIT compilation process. It allows for a more predictable compilation pathway, which in turn leads to performance gains previously unattainable in a dynamically typed language like JavaScript.

At the heart of Static Hermes’ power is its embrace of “sound types.” This feature ensures that the types developers write in their code are the types that the engine uses at runtime, eliminating the dynamic type checks that can slow down execution. It’s a game-changer for performance because it allows Static Hermes to generate native code that runs as efficiently as possible, without the overhead of dealing with unexpected types or JIT deoptimizations.

Static Hermes’ support for TypeScript and Flow is also significant. These systems provide a static type layer on top of JavaScript, and while they have greatly enhanced developer productivity and code reliability, they have not historically impacted runtime performance due to their unsound nature. Static Hermes changes that equation by using these annotations to inform its native compilation process, extracting every ounce of performance from the statically-typed syntax.

The “sound types” in Static Hermes are more than just a stricter set of rules. They are the backbone of a new compilation strategy that combines the predictability of static languages with the dynamism and developer experience of JavaScript. By doing so, Static Hermes not only increases performance but also maintains the delicate balance of JavaScript’s agility and the robustness of a compiled language.

by https://speakerdeck.com/tmikov2023

The significance of Static Hermes lies in its ability to give developers control over performance optimization. It doesn’t force an all-or-nothing approach but instead provides the flexibility to choose which parts of an application can benefit from native compilation. This selective enhancement means that high-priority areas for performance can be addressed without rewriting an entire codebase.

The Technical Breakthrough

This adherence to sound types is key to unlocking native performance; it allows Static Hermes to make strong guarantees about the types it is dealing with, which in turn enables more aggressive and effective optimizations at the native level.

A significant technical innovation introduced by Static Hermes is the zero-cost Foreign Function Interface (FFI). FFI is a mechanism that allows code written in one language to call code written in another language directly. It’s a feature leveraged by systems programming languages like Rust to interface with C libraries without invoking significant overhead. In the context of Static Hermes, zero-cost FFI means that JavaScript code can call into native functions as if it were a native application itself — without the performance penalties typically associated with crossing language boundaries.

This breakthrough is made possible by sound types, which allow the engine to generate highly optimized native bindings for these functions. These bindings are aware of the types they will receive and return, enabling direct calls without runtime type checks or conversions. The zero-cost FFI in Static Hermes essentially eliminates the boundary between JavaScript and native code, treating native functions and JavaScript functions with the same level of efficiency.

The technical underpinnings of Static Hermes also involve sophisticated memory management techniques. By using static types, Static Hermes can allocate and deallocate memory for native types more predictably, avoiding the overhead of garbage collection that can cause pauses and stutters in dynamically typed, garbage-collected languages like JavaScript.

Moreover, the engine can employ LLVM, a collection of modular and reusable compiler and toolchain technologies, to perform advanced optimization techniques such as function inlining, loop unrolling, and vectorization. These optimizations, common in the compilation of static languages, were previously challenging to apply in JavaScript due to its dynamic nature.

In essence, Static Hermes doesn’t just compile JavaScript to native code; it reimagines how the language can be optimized by applying techniques from systems programming to web development. This is the technical breakthrough that could redefine the performance expectations of JavaScript applications, paving the way for JavaScript to extend its reach into domains traditionally reserved for statically typed, compiled languages.

https://github.com/facebook/hermes/tree/static_h

Conclusion & Future Prospects

Static Hermes is set to redefine JavaScript’s capabilities, merging ease of use with high performance. Its evolution will be shaped by community feedback and collaboration. Stay updated and contribute to this exciting journey by following the Hermes GitHub repository and Tzvetan Mikov’s updates on Twitter @tmikov. As Static Hermes progresses, it promises to unlock new possibilities for JavaScript in performance-driven applications.

Feel free to contact me: LinkedIn

--

--

Elves Vieira

Computer Engineer with expertise in JavaScript. Expanding into C# via Asp.net and passionately exploring C++ and Python in my spare time.