react-native icon indicating copy to clipboard operation
react-native copied to clipboard

iOS: Image component uses too much RAM to render images from file system

Open YanislavSpaceIQ opened this issue 1 year ago • 1 comments

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 ( <SafeAreaView> <View style={styles.container}> <Button title={buttonTitle} disabled={!path.length} onPress={toggleShowImage} /> {showImage ? <Image source={{uri: path}} style={styles.image} /> : null} </View> </SafeAreaView> ); };

YanislavSpaceIQ avatar Aug 22 '22 20:08 YanislavSpaceIQ

@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

matpaul avatar Aug 27 '22 11:08 matpaul