Repository navigation
Look up Android image resources without throwing an exception - #59456
Open
hryhoriiK97 wants to merge 1 commit into
Open
hryhoriiK97 wants to merge 1 commit into
hryhoriiK97 wants to merge 1 commit into
Conversation
ResourceDrawableIdHelper.getResourceDrawableId first tried to parse the resource name as a number with toInt() and caught the NumberFormatException. Bundled images in Release builds are drawable resources whose names are not numbers, so every such image source threw an exception and filled in its stack trace. Use toIntOrNull() instead, which parses the same way without throwing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Visual regressionNo visual differences at ios: no capture |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
In Release builds on Android, an image from the bundle (
<Image source={require('./icon.png')} />) is a drawable resource, and its source is the resource name, for exampleassets_icon.ImageSourceturns that name into a URI withResourceDrawableIdHelper.getResourceDrawableId. The same lookup runs fordefaultSourceandloadingIndicatorSource,Image.getSizeof a bundled image, and TextInput'sinlineImageLeft. Images loaded from Metro or from a bundle outside the APK have a URI scheme and don't use it.Current behavior.
getResourceDrawableIdfirst tries the name as a numeric resource id withtoInt()and catches theNumberFormatException. Resource names are not numbers, so every such image source throws an exception and fills in a stack trace as deep as the mount call stack. This happens before the cache of looked-up names, so names that were already looked up throw too. On a Samsung Galaxy A14 the lookup takes about 0.24 ms for each image source, almost all of it in the exception.With this change. The name is parsed with
toIntOrNull(), which accepts the same numbers astoInt()and returnsnullinstead of throwing. Numeric names still return the same id, and other names are still looked up as drawables, so every name gives the same result as before.Changelog:
[ANDROID] [CHANGED] - Images from the app bundle look up their resource without throwing an exception
Test Plan:
--dry-run --set-exit-if-changed) passes on both files.ResourceDrawableIdHelperTest(5 tests: empty name, numeric names, a name looked up as a drawable after normalization, a number too big for anInt, an unknown name). It passes with this change and with the old code, so the results are the same.assembleRelease, arm64-v8a) and compiled withcmd package compile -m speed. The scenario is a local Playground screen, not part of this PR: a long feed with avatars and photos from the bundle that scrolls by itself.adb shell setprop, not part of this PR) that runs either the oldtoInt()withtry/catchortoIntOrNull(), and times every call. Launches alternate A B B A A B B A, 4 per arm. Every launch made 1,300 lookups.getResourceDrawableIdReactImageManager.setSourcewent from 3.5% to 1.6% of the main thread's samples, and the samples in exception handling under it from 237 to 0.🤖 Generated with Claude Code