'Image is showing extremely slow when selecting from ImagePicker

I have not been able to figure out what might be the problem on why after selecting an image it takes 1-3 seconds just to show the picture. The array of images will have no more than 4 images.

I use useState with an array in order to hold all the photos

// PHOTOS
const [photos, setPhotos] = useState([]);

When the component loads. I use useEffect in order to check that we do have selecting images granted as shown below.

useEffect(() => {
  (async () => {
    if (Platform.OS !== "web") {
      const { status } =
        await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (status !== "granted") {
        alert("Sorry, we need camera roll permissions to make this work!");
      }
    }
  })();
}, []);

Next, we have a button that will run the pickImage function. This is responsible for getting the image that was selected, see if it is primary then add it to the array of photos.

const pickImage = async () => {
  // Get the image from the phone
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    allowsMultipleSelection: true,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
    exif: true,
  });

  // Set the photo as primary as true or false
  const photo = {
    isPrimary: photos.length === 0 ? true : false,
    url: result.uri,
  };

  // Update current primary
  if (photo.isPrimary) {
    setCurrentPrimary(photos.length);
  }

  // Add photo to the array
  setPhotos([...photos, photo]);
};

Lastly, we want to make sure we can see these images that are being added. We use a FlatList. This is done as:

<FlatList
  data={photos}
  keyExtractor={(item) => item.url}
  renderItem={({ item, index }) => {
    return (
      <View
        key={index}
        style={{
          flexDirection: "row",
          justifyContent: "space-between",
        }}
      >
        <Text
          style={{
            alignContent: "center",
            alignSelf: "center",
            color: "white",
          }}
        >
          {index + 1}
        </Text>
        <Image
          source={{ uri: item.url }}
          style={{
            height: heightPercentageToDP(20),
            width: widthPercentageToDP(40),
            resizeMode: "contain",
          }}
        />
        <View
          style={{
            flexDirection: "row",
            alignSelf: "center",
            marginRight: 20,
            justifyContent: "space-around",
          }}
        >
          <View
            style={{
              color: item.isPrimary ? "red" : "blue",
            }}
          >
            <Button
              containerStyle={{
                backgroundColor: item.isPrimary ? "red" : "",
              }}
              color={item.isPrimary ? "green" : ""}
              title="Primary"
              onPress={() => makePrimary(index)}
            />
          </View>
          <Button
            color="red"
            title="Remove"
            onPress={() => removeImage(index)}
          />
        </View>
      </View>
    );
  }}
/>;

Any advice on which part might be causing the long lag is really appreciated. Also why this has happened. From my understanding, an array of just 4 images shouldn't cause a long lag and should be nearly instant especially when adding to an array.

Thank you



Solution 1:[1]

I was facing the same issue, I was compressing the quality of images (and compressing needs processing time). I was passing prop compressImageQuality: 0.8 and then I removed it and it started working fine.

My code:

import DatePicker from 'react-native-date-picker';
...
const images = await ImagePicker.openPicker({
    multiple: true,
    maxFiles: 50,
    minFiles: 1,
    mediaType: 'photo',
    compressImageQuality: 0.8, // remove this prop for multiple images
  });

Opinion: Pass following props if you really need them, because they need processing time and I think you should not give these options to user when he is selecting multiple images.

allowsEditing: true, // editing will use mobile resources like cpu, ram, storage ( this will take time ) 
exif: true,

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Muhammad Ahmed Hassan