react-native: "Property storage exceeds 196607 properties" error when using `fetch` more than a certain number of times in React Native
Description
We are developing an application using React Native and Expo. This application needs to run 24/7 and performs network requests using fetch()
regularly for monitoring purposes.
The issue we are facing is that after running the application for a while, from some point, network requests starting to fail. Through investigation using logs from Sentry, we have identified the following problem:
- We are using
fetch()
for network requests. - At the completion of a
fetch()
request, an error occurs:Property storage exceeds 196607 properties
.
The stack trace when this error occurs is as follows:
message: Property storage exceeds 196607 properties,
name: RangeError,
stack:
RangeError: Property storage exceeds 196607 properties
at register (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:13781:20)
at createFromOptions (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:13614:30)
at get (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:13182:67)
at anonymous (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:15155:45)
at call (native)
at dispatchEvent (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:14686:31)
at setReadyState (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:13481:31)
at __didCompleteResponse (/Users/expo/Library/Developer/Xcode/DerivedData/xxx/main.jsbundle:13289:29)
at apply (native)
at anonymous
Through further investigation, the following findings have been uncovered:
- The polyfill used for
fetch
, whatwg-fetch, returns responses asBlob
objects. - When a
Blob
is created, it is registered with blobID in the BlobRegistry, which is not automatically released. - This issue was previously reported in #19248 and was fixed by modifying whatwg-fetch. However, with the implementation of automatic garbage collection in #24405, the implementation was reverted in commit bccc92dfdd2d85933f2a9cb5c8d1773affb7acba, returning to the original behavior.
- Although #24405 enables
Blob
objects to be garbage collected, the Blob IDs registered in the BlobRegistry remain, causing the count to increase each timefetch
is called. - As a result, the
Property storage exceeds 196607 properties
error occurs
Our solution
To address this issue and prevent the error, we have modified the implementation of BlobRegistry
to use a Map
instead of an object. By using a Map, there is no limit to the number of entries.
const registry: Map<String, number> = new Map();
const register = (id: string) => {
const used = registry.get(id);
if (used != null) {
registry.set(id, used + 1);
} else {
registry.set(id, 1);
}
};
const unregister = (id: string) => {
const used = registry.get(id);
if (used != null) {
if (used <= 1) {
registry.delete(id);
} else {
registry.set(id, used - 1);
}
}
};
const has = (id: string): number | boolean => {
return registry.get(id) || false;
};
module.exports = {
register,
unregister,
has,
};
React Native Version
0.72.4
Output of npx react-native info
System: OS: macOS 13.4.1 CPU: (8) arm64 Apple M2 Memory: 92.86 MB / 16.00 GB Shell: version: “5.9” path: /bin/zsh Binaries: Node: version: 18.17.0 path: /usr/local/bin/node Yarn: version: 1.22.19 path: /usr/local/bin/yarn npm: version: 9.6.7 path: /usr/local/bin/npm Watchman: Not Found Managers: CocoaPods: version: 1.12.1 path: /usr/local/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 22.4 - iOS 16.4 - macOS 13.3 - tvOS 16.4 - watchOS 9.4 Android SDK: Not Found IDEs: Android Studio: 2021.2 AI-212.5712.43.2112.8815526 Xcode: version: 14.3/14E222b path: /usr/bin/xcodebuild Languages: Java: Not Found Ruby: version: 3.2.2 path: /Users/takanori.ishikawa/.rbenv/shims/ruby npmPackages: “@react-native-community/cli”: Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.72.4 wanted: 0.72.4 react-native-macos: Not Found npmGlobalPackages: “react-native”: Not Found Android: hermesEnabled: Not found newArchEnabled: Not found iOS: hermesEnabled: Not found newArchEnabled: Not found
Steps to reproduce
Invoke fetch()
more than 196,607 times 😄
Snack, screenshot, or link to a repository
To demonstrate this issue, I created a simple Expo application. https://github.com/ishikawa/react-native-fetch-property-storage-exceeds-error
You can run it with expo:
$ npm i
$ npm run ios
About this issue
- Original URL
- State: closed
- Created 10 months ago
- Reactions: 2
- Comments: 29 (2 by maintainers)
Commits related to this issue
- Use `Map` instead of object in BlobRegistry (#39528) Summary: issue: https://github.com/facebook/react-native/issues/39441 For the following reasons, I have replaced an object used for id management... — committed to facebook/react-native by ishikawa 9 months ago
- Use `Map` instead of object in BlobRegistry (#39528) Summary: issue: https://github.com/facebook/react-native/issues/39441 For the following reasons, I have replaced an object used for id management... — committed to ShevO27/react-native by ishikawa 9 months ago
Observing the same issue on long running app in 0.72.6.
Facing this with react native 0.73.6 as well
0.73.4 still with error here
Above they gave a thumbs up to .72.4 so I assume from that point on… I upgraded to .73 and have not seen it… although I have not tried to recreate it.
Do you guys know which version it is fixed? I am using 0.72.6 and getting this error.
same problem here, when trying to interact (edit or delete) images on bucket
This! Observed with 72.6 and higher.
@ishikawa would you please re-open this issue?
Same issue with
0.73.2
@ishikawa are you sure this is fixed and should be closed?
Will this be in release 0.72.4 and beyond? … I have the same issue.