- 
                Notifications
    You must be signed in to change notification settings 
- Fork 56
Description
We were facing issues with the images/videos in the stories loading very slow. And sometimes, in Android an OutOfMemoryError was thrown when watching the stories.
We did some debugging and when we added some logs in the onLoad() method inside the StoryImage and StoryVideo components, we found out that the images/videos from all stories are loaded when just opening a random story. Since there are lots of stories in our app, especially with videos, this could be quite heavy.
As an optimization we created the patch below. This ensures that the contents inside the StoryList component, including the images/videos, are only initialized for the active story and previous/next story. This way, images/videos are already "preloaded" before the user navigates to the previous/next story, but are not loaded for all other stories at the same time.
We notice huge improvements in our app and didn't receive the OutOfMemoryError yet after we implemented this patch.
I'm curious to hear your opinions on this. If anyone has better ideas, please share them too!
diff --git a/node_modules/@birdwingo/react-native-instagram-stories/src/components/List/index.tsx b/node_modules/@birdwingo/react-native-instagram-stories/src/components/List/index.tsx
index 9fa47d8..3882833 100644
--- a/node_modules/@birdwingo/react-native-instagram-stories/src/components/List/index.tsx
+++ b/node_modules/@birdwingo/react-native-instagram-stories/src/components/List/index.tsx
@@ -1,6 +1,6 @@
-import React, { FC, memo } from 'react';
+import React, { FC, memo, useState } from 'react';
 import Animated, {
-  useAnimatedStyle, useDerivedValue, useSharedValue, withTiming,
+  runOnJS, useAnimatedReaction, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming,
 } from 'react-native-reanimated';
 import StoryAnimation from '../Animation';
 import ListStyles from './List.styles';
@@ -13,7 +13,7 @@ import StoryContent from '../Content';
 import StoryFooter from '../Footer';
 
 const StoryList: FC<StoryListProps> = ( {
-  id, stories, index, x, activeUser, activeStory, progress, seenStories, paused,
+  id, stories, index, x, activeUser, previousUser, nextUser, activeStory, progress, seenStories, paused,
   onLoad, videoProps, progressColor, progressActiveColor, mediaContainerStyle, imageStyles,
   imageProps, progressContainerStyle, imageOverlayView, hideElements, hideOverlayViewOnLongPress,
   videoDuration, loaderColor, loaderBackgroundColor, ...props
@@ -21,6 +21,7 @@ const StoryList: FC<StoryListProps> = ( {
 
   const imageHeight = useSharedValue( HEIGHT );
   const isActive = useDerivedValue( () => activeUser.value === id );
+  const [isInitialized, setIsInitialized] = useState<boolean>(false);
 
   const activeStoryIndex = useDerivedValue(
     () => stories.findIndex( ( item ) => item.id === activeStory.value ),
@@ -41,6 +42,26 @@ const StoryList: FC<StoryListProps> = ( {
     ( item ) => item.id === seenStories.value[id],
   );
 
+  useAnimatedReaction(
+    () => [activeUser.value, previousUser.value, nextUser.value],
+    () => {
+      if (!id) {
+        return;
+      }
+
+      if (id === activeUser.value || id === previousUser.value || id === nextUser.value) {
+        runOnJS(setIsInitialized)(true);
+      }
+    },
+    [activeUser, previousUser, nextUser, id],
+  );
+
+  // Initialize the component only if it is related to the active, previous or next user.
+  // This ensures that assets (videos, images) are loaded selectively for better performance, preventing unnecessary loading for non-visible users.
+  if (!isInitialized) {
+    return null;
+  }
+
   return (
     <StoryAnimation x={x} index={index}>
       <Animated.View style={[ animatedStyles, ListStyles.container ]}>
diff --git a/node_modules/@birdwingo/react-native-instagram-stories/src/components/Modal/index.tsx b/node_modules/@birdwingo/react-native-instagram-stories/src/components/Modal/index.tsx
index dd93855..fdcde31 100644
--- a/node_modules/@birdwingo/react-native-instagram-stories/src/components/Modal/index.tsx
+++ b/node_modules/@birdwingo/react-native-instagram-stories/src/components/Modal/index.tsx
@@ -479,6 +479,8 @@ const StoryModal = forwardRef<StoryModalPublicMethods, StoryModalProps>( ( {
                   index={index}
                   x={x}
                   activeUser={userId}
+                  previousUser={previousUserId}
+                  nextUser={nextUserId}
                   activeStory={currentStory}
                   progress={animation}
                   seenStories={seenStories}
diff --git a/node_modules/@birdwingo/react-native-instagram-stories/src/core/dto/componentsDTO.ts b/node_modules/@birdwingo/react-native-instagram-stories/src/core/dto/componentsDTO.ts
index c1a2ad0..a0b5412 100644
--- a/node_modules/@birdwingo/react-native-instagram-stories/src/core/dto/componentsDTO.ts
+++ b/node_modules/@birdwingo/react-native-instagram-stories/src/core/dto/componentsDTO.ts
@@ -162,6 +162,8 @@ export interface StoryListProps extends InstagramStoryProps, StoryHeaderProps {
   index: number;
   x: SharedValue<number>;
   activeUser: SharedValue<string | undefined>;
+  previousUser: SharedValue<string | undefined>;
+  nextUser: SharedValue<string | undefined>;
   activeStory: SharedValue<string | undefined>;
   progress: SharedValue<number>;
   seenStories: SharedValue<ProgressStorageProps>;