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

Flickering effect when swiping

Open MarcLopezAvila opened this issue 1 year ago • 12 comments

There is a a logic to cause a page change when swiping beyond the middle of the current screen and when that happens there is a flickering effect I understand caused because the internal array of items and buffer are updated. Is there any solution to that? I tried many confugurations but couldn't solve this. It happens also with the most basic example provided. You can notice the flickering while the numbers are updated.

Not sure how the solution should look like but probably, some logic could be done at the end of the swipe to avoid doing it while the user is swiping, causing the flickering effect due to those internal state updates.

Any help would be very appreciated, thanks!

MarcLopezAvila avatar Aug 18 '24 12:08 MarcLopezAvila

As far as I can tell this only happens on Android, I haven't seen it on iOS or on the web.

Here's a video that shows the flickering when passing over the halfway point.

The flickering might not be visible when watching this video on a 60 Hz screen, because the screen recording is 90fps. Watch the video at 0.5x speed to see it.

https://github.com/user-attachments/assets/2291b093-dd08-4453-8020-f32e6825f883

Here's a still frame from one of the flickers, showing that the left page becomes misaligned briefly.

terreng avatar Aug 18 '24 21:08 terreng

I noticed this effect too.

pehkay avatar Aug 20 '24 01:08 pehkay

Does anyone have a solution to it?

MarcLopezAvila avatar Aug 21 '24 09:08 MarcLopezAvila

What version of reanimated are you on? There are known performance issues starting in 3.9.0 that have recently been addressed: https://github.com/software-mansion/react-native-reanimated/issues/6247#issuecomment-2235977637

https://github.com/software-mansion/react-native-reanimated/pull/6218

computerjazz avatar Aug 21 '24 16:08 computerjazz

Hi! Thank you for your quick response @computerjazz , I am using "react-native-reanimated": "3.10.1" which is the one bundled for the latest Expo version 51. I tried to use a different one, either superior or inferior to 3.9.0 but it is not possible since it is bundled with Expo.

I ended up creating a development build with the latest version of reanimated, 3.15.0 and the fickering persists

MarcLopezAvila avatar Aug 21 '24 18:08 MarcLopezAvila

@MarcLopezAvila are you using initialIndex / onPageChange props by any chance?

peterjskaltsis avatar Aug 27 '24 14:08 peterjskaltsis

I am not using initialIndex but I do use onPageChange. My thoughts are that it is because onPageChange is triggered while the user is swiping and not at the end of the swipe so the setStates or anything triggered by the onPageChange is causing some rerender bottleneck and that causes the flickering. I would say that is a common usage anyway.

MarcLopezAvila avatar Aug 27 '24 16:08 MarcLopezAvila

Maybe check if the setState is setting undesired value e.g undefined?

pehkay avatar Aug 28 '24 00:08 pehkay

I am not using onPageChange, but the flickering still happens.

terreng avatar Aug 28 '24 00:08 terreng

does anyone have a solution? I'm not using neither onPageChange, nor initialIndex, but issue still happens. I tried upgrading Reanimated from 3.11.0 to 3.15.1, but no difference as far as I can tell - FPS drops heavily between the pages transition and there is a gap between slides. I'm able to get the FPS down from 60 to 30 by constantly swiping near the transition mark.

audrius-savickas avatar Sep 09 '24 12:09 audrius-savickas

Hi guys, I'm encountering this is issue too. Does someone succeed to solve this ?

"expo": "52.0.37",
"react-native": "0.76.7",
"react-native-reanimated": "3.16.1"
"react-native-infinite-pager": "^0.3.18"

@computerjazz I confirm @audrius-savickas repro method, it constantly happens when swiping near two pages (leaving/entering one)

Also, when I'm commenting setCurIndex(pg), I can see an improvement of the behavior.

I suspect it's a starting point but it's not resolving these frames drop as, even if commented, when navigating to another screen from one container infinite-pager component, we can still feel the FPS drop.

mexysfr avatar Mar 04 '25 20:03 mexysfr

Alright, so it turned to be two different issues on my case :

  1. First one is this flickering effect that was due to expo-image I used as a child of the PageComponent. After some research, I found that there is an ongoing issue / PR for this matter on iOS

This way I've created a PatchedImage and replaced it in my code; then issues stops arising.

import { Image, ImageProps } from 'expo-image'
import { forwardRef } from 'react'
import { Platform } from 'react-native'

/**
 * Patched Image from expo-image with down scaling disabled for iOS only.
 * If down scaling is enabled, image is reloaded to many times.
 * Linked issue: https://github.com/expo/expo/issues/24894
 * Linked PR: https://github.com/expo/expo/pull/24965
 */
export const PatchedImage = forwardRef<Image, ImageProps>(
  ({ ...rest }, ref) => (
    <Image {...rest} ref={ref} allowDownscaling={Platform.OS === 'android'} />
  )
)
  1. Second one was what @audrius-savickas found by swiping near the edge of two pages. I simply fix it by applying following patch
diff --git a/node_modules/react-native-infinite-pager/src/index.tsx b/node_modules/react-native-infinite-pager/src/index.tsx
index e0bfa4a..436236d 100644
--- a/node_modules/react-native-infinite-pager/src/index.tsx
+++ b/node_modules/react-native-infinite-pager/src/index.tsx
@@ -368,15 +368,6 @@ function InfinitePager(
         .onUpdate((evt) => {
           "worklet";
           const evtTranslate = vertical ? evt.translationY : evt.translationX;
-          const crossAxisTranslate = vertical
-            ? evt.translationX
-            : evt.translationY;
-
-          const isSwipingCrossAxis =
-            Math.abs(crossAxisTranslate) > 10 &&
-            Math.abs(crossAxisTranslate) > Math.abs(evtTranslate);
-
-          if (isGestureLocked.value || isSwipingCrossAxis) return;
 
           if (debugTag) {
             console.log(

mexysfr avatar Mar 07 '25 13:03 mexysfr