WhoBuilt

Improving React Native Performance

Oct 8, 2019· 25 min· 6.9K views·Watch on YouTube

Speaker

Tzvetan Mikov, an engineer on Facebook’s Hermes team, explains how Hermes can improve React Native performance at React Native EU 2019, hosted by Callstack.

Mobile performance goals

Mikov introduces Hermes, an open source JavaScript engine built for mobile, and says it had been running most of Facebook’s React Native Android apps for over a year. He focuses on time to interaction, download size, and memory use, especially on phones with limited CPU, RAM, or slow storage. In one Pixel app measurement, Hermes roughly halved startup time and app size and reduced memory use by 30%.

Moving work to build time

Mikov describes how a typical JavaScript engine scans source and compiles functions on the device, then may use JIT compilation for frequently run code. That process can keep source, bytecode, and much larger native code in memory at once. Hermes compiles the bundle on a development computer, optimizes it, and ships compact bytecode so the phone has less work to do at startup.

Loading only what the app needs

Hermes memory-maps its bytecode bundle, allowing modules to be paged into memory when they are required instead of loading the whole bundle at once. Mikov says arranging modules in likely load order can improve sequential reads from flash. Other bundle measures include storing property-name hashes, placing less-needed sections later, deduplicating strings, and moving stack-trace source locations into a separate source map, which he says can make an app 25% smaller.

Compiler optimizations and bytecode

Mikov walks through parsing JavaScript into an abstract syntax tree and converting it to static single-assignment form, which supports compiler optimizations. Hermes can apply React Native-specific measures such as removing function names when an app does not need them and treating selected built-ins as unreplaceable. Its register-based, variable-length bytecode keeps instructions compact; one example function that adds one to a parameter takes nine bytes.

Trying Hermes

Mikov says trying Hermes requires upgrading to React Native later than version 0.60.1 and making a couple of Gradle changes. He invites developers to try it and share feedback, while acknowledging that the engine still has areas to improve.

Takeaways

  • Measure time to interaction, app size, and memory use on devices like those your users have.
  • Moving compilation to build time can reduce the work and memory needed during app startup.
  • Memory-mapped bundles can load required modules on demand instead of bringing the entire bundle into memory.
  • Module ordering and compact bundle metadata can reduce reads from slower flash storage.
  • Check whether your app needs runtime function names or full stack-trace source locations before shipping that data.

Mentioned in this talk

Search inside this talk

What was claimed 12

  • role at
    Tzvetan Mikov is Hermes team member at Meta
    Verified3 sources· Talk
  • feature
    Hermes Agent: In production at Facebook for more than a year, running most of its React Native apps on Android
    “It has been in production at Facebook for more than a year now, running most of our React Native apps on Android.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: Open source JavaScript engine focused on mobile performance
    “Hermes is a brand-new JavaScript engine developed as open source, focusing on mobile performance.”
    YouTube
    Unverified1 source· Talk
  • metric
    Hermes Agent: For one app measured on a Pixel phone: startup performance improved by about half, application size fell by about half, and memory footprint fell 30%.
    “Startup performance improved by about half, application size was down by about half, and memory footprint was down 30%.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: Compiles the source bundle at build time into optimized bytecode
    “We take the whole source bundle and compile it.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: uses memory mapping to load the bytecode bundle at runtime
    uses memory mapping to load the bytecode bundle at runtime
    “At runtime, all that's left to do is memory-map the bundle.”
    YouTube
    Unverified1 source· Talk
  • metric
    Hermes Agent: Bytecode bundle is about 30% smaller than minified JavaScript source
    “This bundle is about 30% smaller than the minified JavaScript source.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: does not use JIT compilation
    does not use JIT compilation
    “There is no JIT in Hermes, and this was a deliberate choice.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: memory-mapped loading can eliminate the need for RAM bundles
    memory-mapped loading can eliminate the need for RAM bundles
    “This ... eliminates the need for technologies like RAM bundles.”
    YouTube
    Unverified1 source· Talk
  • metric
    Hermes Agent: Splitting stack trace data into a separate source map makes the app 25% smaller
    “Hermes has an option that lets you split that data into a separate source map, so now your app gets 25% smaller.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: generates SSA from the parsed syntax tree and uses it for optimization
    generates SSA from the parsed syntax tree and uses it for optimization
    “We generate a static single-assignment form, or SSA, from that tree.”
    YouTube
    Unverified1 source· Talk
  • feature
    Hermes Agent: can optionally eliminate function names from the bundle
    can optionally eliminate function names from the bundle
    “With Hermes, we can eliminate them completely.”
    YouTube
    Unverified1 source· Talk

Related talks