xerdnu / react-native-blasted-image

A simple yet powerful image component for React Native, powered by Glide and SDWebImage.
MIT License
90 stars 10 forks source link

Types, Sizing #2

Closed sepperousseau closed 9 months ago

sepperousseau commented 10 months ago

First of all. Good to see someone started on a replacement for react-native-fast-image it looks promising 👍

I just had a few things that instantly popped up when trying the library by replacing it with the native Image from react-native.

  1. There is currently no typescript support or am I missing something? Might be good to start the library using typescript before it's getting too big.

  2. I saw in the code "if you need width% support log an issue. :D Here I am. Basically a lot of images in our app are sized using styling even without passing width and height. So If I simply swap our Image component all Images are not adapted by the style prop. Currently fixed it by setting the image size based on an onLayout prop inside a wrapper. But that might not be ideal.

  3. Would be nice to have a callback when image is loaded or an extra check function to check if there is an image in the cache. This way we can show a placeholder image if no image is in the cache and fade to the loaded image when done. Or the library could do that as well. But that might be a little much in early stage :)

Happy to hear your thoughts. Keep up the good work 👍

xerdnu commented 10 months ago

Hi @sepperousseau ,

First of all, thank you for your detailed ideas and glad to hear your thoughts.

I will start look into this after the weekend.

The reason i removed the width% feature is because i believe the onLayout event will have a tiny impact on performance and that i did not have the need for it cause i only use pre-calculated width/height. But i will add that for you.

Handling loaded images:

  1. (Fast) You can use async promise for knowing when the image was loaded or error occured.
  2. (Not as fast) the Event that can be found in the documentation.

I will also look into adding a method that checks if the image is in cache. I am preloading all images to disk when my app is loading so i did not have the need for that function but it will be added 😄

Thanks again for your ideas and best regards! 🚀

sepperousseau commented 10 months ago

Hi @xerdnu

I currently updated all my images with fixed sizing :D might be better for performance. So the sizing is not that important anymore.

For the async promise you mean calling the loadImage myself?

Also I noticed the package name for android is still default package="com.reactlibrary" Maybe you can rename it :)

xerdnu commented 10 months ago

@sepperousseau

That sounds good!

When using onLayout there will be a tiny delay due to the state update in combination with the onLayout event so i found that passing the fixed size down to the image module works best in terms of performance to avoid flickering and unnecessary delay. Maybe someone else has some better idea on how to handle this without using onLayout and states.

Also Glide is not built with the functionality to check if a image is cached or not out of the box. Implementing this check will make it cache the image and manually remove it and this will just be draining resources in my opinion. I would recommend preloading the image at some point. Please note that if the image is already found in cache Glide will not download it again so there is no downside there.

Also regarding your question about the loaded image callback i will post some code below.

Using preload

const processItem = async (image) => {
    try {
        await BlastedImage.preload({
        uri: image,
        skipMemoryCache: true // if you want to only store it to disk and not allocate memory
        });
        console.log("Image done loading here");
    } catch (error) {
        console.error("Error preloading image:", error);
    }
};

processItem("https://example.image.url.png");

Without preload you can listen to the event

import { NativeEventEmitter, NativeModules } from 'react-native';

const BlastedImageEvents = new NativeEventEmitter(NativeModules.BlastedImage);

useEffect(() => {
  const subscription = BlastedImageEvents.addListener('BlastedEventLoaded', (data) => {
    console.log(data.message); // Image was loaded from network/disk/memory and also shown
  });

  return () => {
    subscription.remove();
  };
}, []);

I will push a new package name in the next patch. Thanks for the feedback and let me know if the code above works for you or if you want something else 😃 🚀

dFelinger commented 10 months ago

It would be great if you add onLoad prop like in standard react native Image component.

xerdnu commented 10 months ago

@dFelinger

Added in 0.0.12 with #3.

Credits go to @sepperousseau

Karrthik-Arya commented 8 months ago

Will support for width% feature be added anytime soon?