react-native
react-native copied to clipboard
iOS: Image component uses too much RAM to render images from file system
Description
iOS: Image component uses 300mb of RAM to render image that is actually 8mb.
Version
0.69.4
Output of npx react-native info
System: OS: macOS 12.4 CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz Memory: 109.60 MB / 32.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.15.1 - /usr/local/bin/node Yarn: 1.22.11 - /usr/local/bin/yarn npm: 8.11.0 - /usr/local/bin/npm Watchman: Not Found Managers: CocoaPods: 1.11.3 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5 Android SDK: API Levels: 29, 31 Build Tools: 29.0.2, 29.0.3, 30.0.2, 30.0.3, 31.0.0 System Images: android-29 | Intel x86 Atom_64, android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom Android NDK: Not Found IDEs: Android Studio: 2021.2 AI-212.5712.43.2112.8609683 Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild Languages: Java: 1.8.0_292 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.0.0 => 18.0.0 react-native: 0.69.4 => 0.69.4 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found
Steps to reproduce
For example I used fetch-blob library to download image and store it in the file system, but you can reproduce it without using this library: just put some image (I used 8.4mb image) to the phone file system and use path to this image as uri for Image component's source prop.
Snack, code example, screenshot, or link to a repository
import React, {useEffect, useReducer, useState} from 'react'; import RNFetchBlob from 'rn-fetch-blob'; import {SafeAreaView} from 'react-native-safe-area-context'; import {Button, Image, StyleSheet, View} from 'react-native';
const styles = StyleSheet.create({ container: { width: '100%', justifyContent: 'center', alignItems: 'center', height: 80, }, image: { width: 40, height: 40, borderRadius: 20, resizeMode: 'cover', }, });
const url = 'https://www.learningcontainer.com/bfd_download/large-sample-image-file-download-for-testing/';
export const Header = () => { const [path, setPath] = useState(''); const [showImage, toggleShowImage] = useReducer(value => !value, false);
useEffect(() => {
(async () => {
try {
const localPath = ${RNFetchBlob.fs.dirs.CacheDir}/image
;
const exists = await RNFetchBlob.fs.exists(localPath);
if (exists) {
setPath(localPath);
return;
}
const fetchBlob = RNFetchBlob.config({
path: localPath,
appendExt: 'jpeg',
});
const response = await fetchBlob.fetch('GET', url);
setPath(response.path());
} catch (e) {
console.log('Error', e);
}
})();
}, []);
const buttonTitle = ${showImage ? 'Hide' : 'Show'} image
;
return (
@YanislavSpaceIQ Hi, size of file and size of RAM used to show should not be the same Actual size of decoded image in RAM: width * height * pixel_format, in your example 7200 * 5400 * 3(RGB) * 8 bit ~ 116.64mb