dohooo / react-native-reanimated-carousel

🎠 React Native swiper/carousel component, fully implemented using reanimated v2, support to iOS/Android/Web. (Swiper/Carousel)
https://react-native-reanimated-carousel.vercel.app
MIT License
2.81k stars 324 forks source link

Scrolling between components is smooth in simulator but laggy on real device #209

Closed hy-atoz closed 2 years ago

hy-atoz commented 2 years ago

Describe the bug I'm using this package to create full page horizontal view scrolling between components. As the title said, the scrolling is smooth when I test it in a simulator (both iOS and Android). However, when I test it on a real device, I notice that it is laggy when I start to do the scrolling.

Is it because this package is suitable for images, but not for full page component? Or how should I optimise my code to make it smoother?

To Reproduce Steps to reproduce the behavior, here is my code:

// import statements

const {height: PAGE_HEIGHT, width: PAGE_WIDTH} = Dimensions.get('window');
const activeOffsetX = {activeOffsetX: [-10, 10]};

const App = () => {
  const resultRef = useRef(null);
  const [currentSide, setCurrentSide] = useState('M');
  const [isVertical] = useState(false);

  // other code

  // Base options for <Carousel />
  const baseOptions = isVertical
    ? {
        vertical: true,
        height: PAGE_HEIGHT,
        width: PAGE_WIDTH,
      }
    : {
        vertical: false,
        height: PAGE_HEIGHT,
        width: PAGE_WIDTH,
      };

 // other code

  return (
    <SafeAreaView style={styles.container}>
      {isLoading && !isLiveStarted ? <FullScreenLoading /> : null}
      <AppTitle />
      {result.length === 0 ? (
        <Carousel
          {...baseOptions}
          data={c}
          defaultIndex={0}
          panGestureHandlerProps={activeOffsetX}
          ref={blankResultRef}
          renderItem={({index}) => {
            return (
              <BlankResultScreen
                key={index}
                index={index}
                bgColor={c[index].color}
                hasLetter={c[index].hasLetter}
                isBlackText={c[index].isBlackText}
                isGreenText={c[index].isGreenText}
                name={c[index].name}
                source={c[index].image}
              />
            );
          }}
        />
      ) : (
        <Carousel
          {...baseOptions}
          data={c}
          defaultIndex={0}
          onSnapToItem={index => setCurrentSide(c[index].code)}
          pagingEnabled={false}
          panGestureHandlerProps={activeOffsetX}
          ref={resultRef}
          renderItem={({index}) => {
            return (
                <ResultScreen
                  key={index}
                  index={index}
                  bgColor={c[index].color}
                  companyCode={c[index].code}
                  hasLastRow={c[index].hasLastRow}
                  hasLetter={c[index].hasLetter}
                  hasLiveVideo={c[index].hasLiveVideo}
                  isBlackText={c[index].isBlackText}
                  isGreenText={c[index].isGreenText}
                  name={c[index].name}
                  source={c[index].image}
              </>
            );
          }}
        />
      )}
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default codePush(codePushOptions)(App);

Expected behavior Scrolling between every view should be smooth on real devices.

Screen record https://user-images.githubusercontent.com/105196702/175454414-e4ec3a40-a6ff-4bb9-bf6e-b08710f43220.mp4

Versions (please complete the following information):

Smartphone (please complete the following information):

oliverloops commented 2 years ago

Hi @hy-atoz 👋, I notice that you're not using the windowSize prop. I recommend you to use it as a first solution when you encounter with some of this performance issues that produces laggy transitions, this props helps you rendering some of the views avoiding overloading and increasing performance when you have multiple elements. The library can handle complex layouts eg. grouped components, multiple rendered elements in the same view etc., we actually called this complex carousel, there's a great possibility that your own full page components aren't causing the issue.

I was doing some intensive elements rendering inside the core <Carousel /> component changing the windowSize prop parameters and I recommend you to use values between 3 - 5.

I'll hope this helps.

hy-atoz commented 2 years ago

Hi @hy-atoz 👋, I notice that you're not using the windowSize prop. I recommend you to use it as a first solution when you encounter with some of this performance issues that produces laggy transitions, this props helps you rendering some of the views avoiding overloading and increasing performance when you have multiple elements. The library can handle complex layouts eg. grouped components, multiple rendered elements in the same view etc., we actually called this complex carousel, there's a great possibility that your own full page components aren't causing the issue.

I was doing some intensive elements rendering inside the core <Carousel /> component changing the windowSize prop parameters and I recommend you to use values between 3 - 5.

I'll hope this helps.

Hi @oliverloops, thank you for the suggestion! I've tried adding the windowSize prop, but the problem still exist.

As for now, when I scroll through the carousel very quickly, the performance is excellent, as you can see in the screen record. But when I do it slower, you can see that it is not as smooth as when the movement is fast.

Do you have any idea why is this happening?

https://user-images.githubusercontent.com/105196702/176452550-7e28beec-52a6-4292-bbaa-e5733687c20a.mp4

oliverloops commented 2 years ago

Thanks for share!. yes I notice the same behavior when the swipe gesture is slower there is a noticeable FPS dropping. Let's me see what's happening under the hood and see If I can fix it quickly

dohooo commented 2 years ago

Thanks for share, Have you tried the latest version of RNRC? 3.0.3

dohooo commented 2 years ago

I'll reopen this issue If you have any other questions.

AndonMitev commented 1 year ago

Guys any progress with the issue?

birloiflorian commented 1 year ago

Guys any development for workarounds regarding this issue?

chanphiromsok commented 5 months ago

display 100 images , scrolling is laggy I'm using Image from expo not react-native

const { width } = Dimensions.get('window');
const slideWidth = width - 20;
const slideHeight = slideWidth * 0.55;
const BannerSlider = () => {
  const { data, isLoading, isFetched } = useQueryBanner();
  const sliderData = data || [];
  const enabledSlide = !!sliderData?.[1];
  const renderItem = useCallback(({ item }: { item: Slider }) => {
    const source = { uri: item.image };
    return (
      <Container style={styles.slideItem}>
        <Image source={source} style={styles.slideImage} />
      </Container>
    );
  }, []);
  if (isLoading) {
    return <Container style={styles.slideWrap} />;
  }
  if (isFetched && !sliderData?.[0]) {
    return null;
  }
  return (
    <Carousel
      data={sliderData}
      loop={enabledSlide}
      enabled={enabledSlide}
      renderItem={renderItem}
      width={width}
      autoPlay
      height={slideHeight}
      windowSize={3}
      mode="parallax"
      modeConfig={modeConfig}
      withAnimation={withAnimation}
      panGestureHandlerProps={panGestureHandlerProps}
      autoPlayInterval={3000}
    />
  );
};

export default memo(BannerSlider);
const styles = StyleSheet.create({
  slideWrap: {
    width,
    height: slideHeight,
    borderRadius: 5,
  },
  slideItem: {
    width,
    height: slideHeight,
    overflow: 'hidden',
    borderRadius: 10,
  },
  slideImage: { flex: 1 },
});
const modeConfig = {
  // scale mid item
  parallaxScrollingScale: 0.9,
  // horizontal space of mid item
  parallaxScrollingOffset: 0.1 * width - 8,
  // scale left item and right item
  parallaxAdjacentItemScale: 0.89,
};
const withAnimation: TCarouselProps['withAnimation'] = {
  type: 'timing',
  config: {
    duration: 350,
    easing: Easing.linear,
  },
};

const panGestureHandlerProps = {
  activeOffsetX: [-10, 10],
};