From 097073fcd3fd6aafa707a8a0df392445ab4ebe96 Mon Sep 17 00:00:00 2001 From: tapframe Date: Wed, 10 Sep 2025 15:16:05 +0530 Subject: [PATCH] homescreen optomziation --- src/components/home/CatalogSection.tsx | 9 ++++++--- src/components/home/ContentItem.tsx | 28 +++++++++++++++++--------- src/screens/HomeScreen.tsx | 13 ++++++------ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/components/home/CatalogSection.tsx b/src/components/home/CatalogSection.tsx index cbf6cf63..ffdbf0a1 100644 --- a/src/components/home/CatalogSection.tsx +++ b/src/components/home/CatalogSection.tsx @@ -61,11 +61,15 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => { navigation.navigate('Metadata', { id, type, addonId: catalog.addon }); }, [navigation, catalog.addon]); - const renderContentItem = useCallback(({ item }: { item: StreamingContent, index: number }) => { + const renderContentItem = useCallback(({ item, index }: { item: StreamingContent, index: number }) => { + // Only load images for the first few items eagerly; others defer based on viewability + const eager = index < 6; return ( ); }, [handleContentPress]); @@ -108,8 +112,7 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => { ItemSeparatorComponent={ItemSeparator} onEndReachedThreshold={0.7} onEndReached={() => {}} - scrollEventThrottle={16} - estimatedItemSize={POSTER_WIDTH + 8} + scrollEventThrottle={32} /> ); diff --git a/src/components/home/ContentItem.tsx b/src/components/home/ContentItem.tsx index 3893384b..80331119 100644 --- a/src/components/home/ContentItem.tsx +++ b/src/components/home/ContentItem.tsx @@ -10,6 +10,8 @@ import { DropUpMenu } from './DropUpMenu'; interface ContentItemProps { item: StreamingContent; onPress: (id: string, type: string) => void; + shouldLoadImage?: boolean; + deferMs?: number; } const { width } = Dimensions.get('window'); @@ -56,12 +58,12 @@ const POSTER_WIDTH = posterLayout.posterWidth; const PLACEHOLDER_BLURHASH = 'LEHV6nWB2yk8pyo0adR*.7kCMdnj'; -const ContentItem = ({ item, onPress }: ContentItemProps) => { +const ContentItem = ({ item, onPress, shouldLoadImage: shouldLoadImageProp, deferMs = 0 }: ContentItemProps) => { const [menuVisible, setMenuVisible] = useState(false); const [isWatched, setIsWatched] = useState(false); const [imageLoaded, setImageLoaded] = useState(false); const [imageError, setImageError] = useState(false); - const [shouldLoadImage, setShouldLoadImage] = useState(false); + const [shouldLoadImageState, setShouldLoadImageState] = useState(false); const [retryCount, setRetryCount] = useState(0); const { currentTheme } = useTheme(); const { settings } = useSettings(); @@ -111,14 +113,22 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => { setMenuVisible(false); }, []); - // Lazy load images - only load when likely to be visible + // Lazy load images - only load when asked by parent (viewability) or after small defer useEffect(() => { + if (shouldLoadImageProp !== undefined) { + if (shouldLoadImageProp) { + const t = setTimeout(() => setShouldLoadImageState(true), deferMs); + return () => clearTimeout(t); + } else { + setShouldLoadImageState(false); + } + return; + } const timer = setTimeout(() => { - setShouldLoadImage(true); - }, 50); // Reduced delay for faster loading - + setShouldLoadImageState(true); + }, 80); return () => clearTimeout(timer); - }, []); + }, [shouldLoadImageProp, deferMs]); // Get optimized poster URL for smaller tiles const getOptimizedPosterUrl = useCallback((originalUrl: string) => { @@ -158,12 +168,12 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => { > {/* Only load image when shouldLoadImage is true (lazy loading) */} - {shouldLoadImage && item.poster ? ( + {(shouldLoadImageProp ?? shouldLoadImageState) && item.poster ? ( { let catalogIndex = 0; // Limit concurrent catalog loading to prevent overwhelming the system - const MAX_CONCURRENT_CATALOGS = 1; // Single catalog at a time to minimize heating + const MAX_CONCURRENT_CATALOGS = 1; // Single catalog at a time to minimize heating/memory let activeCatalogLoads = 0; const catalogQueue: (() => Promise)[] = []; @@ -196,8 +196,9 @@ const HomeScreen = () => { const metas = await stremioService.getCatalog(manifest, catalog.type, catalog.id, 1); if (metas && metas.length > 0) { - // Limit items per catalog to reduce memory usage - const limitedMetas = metas.slice(0, 30); + // Aggressively limit items per catalog on Android to reduce memory usage + const limit = Platform.OS === 'android' ? 18 : 30; + const limitedMetas = metas.slice(0, limit); const items = limitedMetas.map((meta: any) => ({ id: meta.id, @@ -217,7 +218,7 @@ const HomeScreen = () => { certification: meta.certification })); - // Skip prefetching to reduce memory pressure + // Skip prefetching to reduce memory pressure (keep disabled) // Resolve custom display name; if custom exists, use as-is const originalName = catalog.name || catalog.id; let displayName = await getCatalogDisplayName(addon.id, catalog.type, catalog.id, originalName); @@ -282,7 +283,7 @@ const HomeScreen = () => { // Initialize catalogs array with proper length setCatalogs(new Array(catalogIndex).fill(null)); - // Start processing the catalog queue (parallel fetching continues in background) + // Start processing the catalog queue processCatalogQueue(); } catch (error) { if (__DEV__) console.error('[HomeScreen] Error in progressive catalog loading:', error); @@ -650,7 +651,7 @@ const HomeScreen = () => { const renderListItem = useCallback(({ item, index }: { item: HomeScreenListItem, index: number }) => { const wrapper = (child: React.ReactNode) => ( - + {child} );