mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
homescreen optomziation
This commit is contained in:
parent
ccde944bfa
commit
097073fcd3
3 changed files with 32 additions and 18 deletions
|
|
@ -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 (
|
||||
<ContentItem
|
||||
item={item}
|
||||
onPress={handleContentPress}
|
||||
shouldLoadImage={eager}
|
||||
deferMs={eager ? 0 : Math.min(400 + index * 15, 1500)}
|
||||
/>
|
||||
);
|
||||
}, [handleContentPress]);
|
||||
|
|
@ -108,8 +112,7 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => {
|
|||
ItemSeparatorComponent={ItemSeparator}
|
||||
onEndReachedThreshold={0.7}
|
||||
onEndReached={() => {}}
|
||||
scrollEventThrottle={16}
|
||||
estimatedItemSize={POSTER_WIDTH + 8}
|
||||
scrollEventThrottle={32}
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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) => {
|
|||
>
|
||||
<View ref={itemRef} style={[styles.contentItemContainer, { borderRadius: posterRadius }] }>
|
||||
{/* Only load image when shouldLoadImage is true (lazy loading) */}
|
||||
{shouldLoadImage && item.poster ? (
|
||||
{(shouldLoadImageProp ?? shouldLoadImageState) && item.poster ? (
|
||||
<ExpoImage
|
||||
source={{ uri: getOptimizedPosterUrl(item.poster) }}
|
||||
style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1, borderRadius: posterRadius }]}
|
||||
contentFit="cover"
|
||||
cachePolicy="memory-disk" // Use both memory and disk cache
|
||||
cachePolicy={Platform.OS === 'android' ? 'disk' : 'memory-disk'}
|
||||
transition={0} // Disable transition to reduce GPU work
|
||||
placeholder={{ blurhash: PLACEHOLDER_BLURHASH } as any}
|
||||
placeholderContentFit="cover"
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ const HomeScreen = () => {
|
|||
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<void>)[] = [];
|
||||
|
||||
|
|
@ -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) => (
|
||||
<Animated.View entering={FadeIn.duration(350).delay(Math.min(index * 70, 700))}>
|
||||
<Animated.View>
|
||||
{child}
|
||||
</Animated.View>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue