Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace RCTLocalAssetImageLoader to RCTBundleAssetImageLoader (#37232)
Summary: From the video below, we can see that the UI thread has dropped many frames, and it would become worse if there are multiple images. If an image is located in the sandbox of the disk, we cannot load it using `RCTLocalAssetImageLoader` because `RCTLocalAssetImageLoader.requiresScheduling` is set to true, which loads the data on the UI thread and causes main thread stuttering. This will affect libraries such as `react-native-code-push` and others that save images to the sandbox of the disk. Therefore, we should replace `RCTLocalAssetImageLoader.canLoadImageURL` from `RCTIsLocalAssetURL(url)` to `RCTIsBundleAssetURL(url)`. Similarly, we should rename the entire `RCTLocalAssetImageLoader` file with `RCTBundleAssetImageLoader`, which ignores images in the disk sandbox. And finally these images will be loaded from `NSURLRequest`, and our UI thread will run smoothly again. https://user-images.githubusercontent.com/20135674/236368418-8933a2c6-549c-40d3-a551-81b492fe41d5.mp4 ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [IOS] [Breaking] - Replace `RCTLocalAssetImageLoader` to `RCTBundleAssetImageLoader` Pull Request resolved: #37232 Test Plan: Test Code: ```javascript constructor(props) { super(props) this.state = { bundle_image: require('./large_image.png'), sandbox_image: '', source: null, isLoading: false, } } render() { console.log('render', this.state) return ( <View style={{ flex: 1, padding: 50, backgroundColor: 'white'}}> <View style={{ flexDirection: 'row', alignItems: 'center', height: 70}}> { [{ title: 'Save Image To SandBox', onPress: () => { let image = Image.resolveAssetSource(this.state.bundle_image) console.log(image.uri) this.setState({ isLoading: true }) RNFetchBlob.config({ fileCache: true, appendExt: "png" }).fetch("GET", image.uri).then(response => { let path = response.path() path = /^file:\/\//.test(path) ? path : 'file://' + path console.log(path) this.state.sandbox_image = path }).finally(() => this.setState({ isLoading: false })) }}, { title: 'Load From SandBox', onPress: () => { this.setState({ source: { uri: this.state.sandbox_image } }) }}, { title: 'Clear', onPress: () => { this.setState({ source: null, isLoading: false }) }}, { title: 'Load From Bundle', onPress: () => { this.setState({ source: this.state.bundle_image }) }}].map((item, index) => { return ( <Pressable key={index} style={{ height: '100%', justifyContent: 'center', flex: 1, borderWidth: 1, borderColor: 'black', marginLeft: index > 0 ? 15 : 0 }} onPress={item.onPress} > <Text style={{ textAlign: 'center' }}>{item.title}</Text> </Pressable> ) }) } </View> <ActivityIndicator style={{ marginTop: 10 }} animating={this.state.isLoading} /> <Image key={`${this.state.source}`} style={{ marginTop: 20, width: 200, height: 200 }} source={this.state.source} onProgress={({ nativeEvent }) => console.log(nativeEvent)} onLoadStart={() => this.setState({ isLoading: true })} onLoadEnd={() => this.setState({ isLoading: false })} /> </View> ) } ``` It needs to be tested in three environments: [Simulator_Debug, RealDevice_Debug, RealDevice_Release] 1. Open `Perf Monitor` (RealDevice_Release can be skipped) 2. Click `Save Image to SandBox` 3. Wait for the loading to end and click `Load From SandBox` 4. Verify that the image can be loaded successfully 5. Verify that the `UI thread` keeps `60 FPS` (RealDevice_Release can be skipped) 6. Click `Clear` 7. Repeat steps [3, 4, 5, 6] several times 8. Click `Load From Bundle` to verify that the bundle image can be loaded successfully Simulator_Debug https://user-images.githubusercontent.com/20135674/236369344-ee1b8ff1-2d49-49f3-a322-d973f4adf3e7.mp4 RealDevice_Debug https://user-images.githubusercontent.com/20135674/236369356-fe440b2b-f72a-49be-b63c-b4bf709dac8c.mp4 RealDevice_Release https://user-images.githubusercontent.com/20135674/236369365-8a6a5c2f-09ad-4c90-b6bd-41e8a5e3aa7f.mp4 Reviewed By: rshest Differential Revision: D46441513 Pulled By: dmytrorykun fbshipit-source-id: 652febd4147dbff6c1ceef03d84ce125b8c66770
- Loading branch information