Skip to content

Conversation

tsapeta
Copy link
Contributor

@tsapeta tsapeta commented Oct 10, 2025

Summary:

In Expo, someone reported (expo/expo#40158) that expo-image-manipulator causes memory crashes when processing large images (> 30MB).
Image manipulator uses RCTImageLoader to load and decode images. As opposed to the Image component, it always requests for images in full size. For large images it may crash at CGImageSourceCreateThumbnailAtIndex which in the provided repro slowly increases memory usage until it finally crashes after a few seconds of running.
I figured out that not including the kCGImageSourceThumbnailMaxPixelSize option works much better, but using CGImageSourceCreateImageAtIndex instead of CGImageSourceCreateThumbnailAtIndex works even better – it's faster and consumes less memory during decoding. This is more or less what SDWebImage library does, see SDImageIOAnimatedCoder.
With the proposed changes, it's still crashing but only for the largest image (64MB), other images (40MB and 50MB) are now working fine. Obviously, it cannot be fixed entirely and it's not recommended to load such big images without downscaling them.

Changelog:

[IOS] [CHANGED] - Use CGImageSourceCreateImageAtIndex instead of CGImageSourceCreateThumbnailAtIndex to decode full-sized images

Test Plan:

I've tested the examples of the Image component in RNTester as well as the repro provided in expo/expo#40158

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 10, 2025
@facebook-github-bot facebook-github-bot added p: Software Mansion Partner: Software Mansion Partner p: Expo Partner: Expo labels Oct 10, 2025
@tsapeta tsapeta force-pushed the faster-full-size-image-decoding branch from 45896bc to cf8b5f2 Compare October 15, 2025 12:57
@tsapeta tsapeta marked this pull request as ready for review October 16, 2025 09:28
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 16, 2025
Copy link
Contributor

@cipolleschi cipolleschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me... but I'm not sure whether there might be implications in the product code internally.

I'll import it and ask for more eyes on it.

Copy link

meta-codesync bot commented Oct 16, 2025

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this in D84835416.

cipolleschi pushed a commit to cipolleschi/react-native that referenced this pull request Oct 17, 2025
Summary:
In Expo, someone reported (expo/expo#40158) that `expo-image-manipulator` causes memory crashes when processing large images (> 30MB).
Image manipulator uses `RCTImageLoader` to load and decode images. As opposed to the Image component, it always requests for images in full size. For large images it may crash at `CGImageSourceCreateThumbnailAtIndex` which in the provided repro slowly increases memory usage until it finally crashes after a few seconds of running.
I figured out that not including the `kCGImageSourceThumbnailMaxPixelSize` option works much better, but using `CGImageSourceCreateImageAtIndex` instead of `CGImageSourceCreateThumbnailAtIndex` works even better – it's faster and consumes less memory during decoding. This is more or less what `SDWebImage` library does, see [`SDImageIOAnimatedCoder`](https://github.com/SDWebImage/SDWebImage/blob/master/SDWebImage/Core/SDImageIOAnimatedCoder.m#L488-L509).
With the proposed changes, it's still crashing but only for the largest image (64MB), other images (40MB and 50MB) are now working fine. Obviously, it cannot be fixed entirely and it's not recommended to load such big images without downscaling them.

## Changelog:

[IOS] [CHANGED] - Use `CGImageSourceCreateImageAtIndex` instead of `CGImageSourceCreateThumbnailAtIndex` to decode full-sized images


Test Plan: I've tested the examples of the `Image` component in RNTester as well as the repro provided in expo/expo#40158

Reviewed By: javache

Differential Revision: D84835416

Pulled By: cipolleschi
@meta-codesync meta-codesync bot closed this in be4fcda Oct 17, 2025
@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Oct 17, 2025
Copy link

meta-codesync bot commented Oct 17, 2025

@cipolleschi merged this pull request in be4fcda.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. p: Expo Partner: Expo p: Software Mansion Partner: Software Mansion Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants