hermes: Hermes object property limit causes problems with real use cases

Problem

In development I want to load my source maps into my react-native app so I can parse and pretty print stacks with more useful locations. This works fine on JSC or V8 but cannot be done on hermes due to RangeError: Property storage exceeds 196607 properties.

Is the properly limit an important hard and fast requirement for hermes goals? Could it be lifted higher or lifted only in development mode?

Solution

Raise the hard limit on object properties so that large data structures such as source maps are usable with hermes.

Additional Context

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 10
  • Comments: 27 (11 by maintainers)

Commits related to this issue

Most upvoted comments

@tmikov So what is the approximate time window of new release? Is it going to be this year?

I see this every morning when I come back to my simulator that was open all night, so it’s only in the dev environment (iOS).

Update: this issue will be addressed by the next major release of Hermes.

To add another real world example, where 3rd party code is internally using a plain object to track unique keys even though our own code is only using arrays.

For context our app handles large amounts of data, with multiple record types and some record types having ~300k records for certain customers.

import { uniqBy } from "lodash";

var largeArray = Array.from({ length: 200000 }).map(
  () => Math.random(),
  (item) => item
);

var result = uniqBy(largeArray);

globalThis.console?.log ? console.log(result) : print(result);

(bundled with npx esbuild --bundle in.js --outfile=out.js --target=es5 for testing and ran with the hermes cli)

This works fine in other JS engines but crashes in Hermes. I get that certain tradeoffs were made with this 4MB heap segment size but given React Native is pushing for Hermes to be the default it leaves us in a frustrating position where there’s no easy path forward without rewriting large parts of our app, and then having to replace or patch a number of third party dependencies.

Of course one alternative is us maintaining custom Hermes builds with a larger segment size but we’d prefer to keep React Native as standard as possible to avoid future upgrade pain.

Just wanted to highlight that it’s not always as simple as ‘fix your code’. Sure we can do that and use Map instead of plain objects wherever necessary, but external dependencies are the hidden part of the iceberg here.

I just want to add credence to the idea that sometimes there are real-world use cases that are impacted by this:

Our team is running into this issue because of our usage of URQL’s graphcache. When we go to write the cache to the disk, it provides us the cache as an object and we often have more than 196k entities in the graphQL cache so we hit this limit.

With JSI being so common now in react-native libraries, using JavaScriptCore sucks because it means we can’t run the app in a debugger anymore due to JSI calls. I really don’t want to have to switch back to JSC but this deviation from the behavior of every other common JS runtime might force us to.

Thanks for the tip @tmikov, unfortunately there doesn’t yet seem to be a simple way to build hermes from source as part of a react-native build.

This is a development mode only issue for me so it doesn’t really have a huge impact although the dev experience was a lot nicer being able to leverage source maps from inside the app. React-native dev tooling is pretty painful in general (flipper is massively buggy, android crashes a lot, source maps don’t work well, metro doesn’t support symlinks, dependent upon millisecond clock sync between host and device, debugger usually doesn’t work, docs are misleading and outdated, and so on) so anything to ease that a bit is pretty valuable at least to me.

I agree in non-dev situations it probably doesn’t make sense to be building objects with > 200k properties, but for development mode in react-native it can be useful as I outlined above.

@seavan it is on our radar and will be addressed before the release of Static Hermes, meaning in 2024, but I can’t really be more specific than that unfortunately.