React Native - VisibilityDetector.measure() causes Excessive number of pending callbacks
on low spec Android devices
#103
Labels
bug
Something isn't working
Hello there,
I am currently using react-native components library in an app that I'm developing. Basically, I have a react-native
FlatList
that renders a Component which is a thumbnail (usingTwicImg
) with some additional informations but just<View>
and<Text>
components.Recently, I've experienced some performance issues when running my app on Android (emulator and 2017 Samsung Galaxy S8). When I navigate between screens that render
TwicImg
components, sometimes (it's hard to reproduce consistently), I have this error :From my research, as it says, this warning is due to asynchronous callbacks that are stacking up again and again, hence leading to the JS thread being saturated.
It was really hard to track this issue down since the code is minified and obfuscated, but after building it from the source and disabling
terser
minification / formatting options, I managed to track down where the problem comes from.The Visibility Detector component has a
useEffect
that waits until the media has reached the viewport (ifeager
prop is not set to true of course) to change the visibility of the media.https://github.com/TwicPics/components/blob/main/src/react-native/visibilityDetector.tsx#L74-L83
Problem is, the
observe
function sets an interval withsetInterval
to check the media position relative to the viewport. The default interval for this call is 100ms, no matter the execution time of themeasure
function. If themeasure
execution time is greater than the interval, callbacks are stacked and this leads to my issue below.It basically happens where I have a list of some items which are mounted (so the useEffect has been triggered), but the image is not visible to the screen because I don't scroll enough to see it. So the measurement is done again and again. To make sure the error was from there, I added some logs to measure the execution of the
measure
function. On IOS, it takes few ms to be triggered, but on low spec Android devices, it can take up to 600-700ms.I might set the
eager
prop totrue
as a workaround, and I know that I can also increase themeasurementInterval
but I think that the main issue is the use ofsetInterval
, which schedule a call regardless of the previous measurement completion. I think asetTimeout
at the end of themeasure
function will ensure that the measurement will be performedmeasurementInterval ms
AFTER the last execution, thus preventing the callbacks to be stacked.I'm using react-native
0.72.10
with exposdk 49
.Great job by the way !
Cheers,
Chris
The text was updated successfully, but these errors were encountered: