mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-28 13:28:48 +00:00
heating optimization
This commit is contained in:
parent
02bfd85b5a
commit
6bb4d927ed
8 changed files with 34 additions and 47 deletions
|
|
@ -164,10 +164,11 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => {
|
|||
style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1, borderRadius: posterRadius }]}
|
||||
contentFit="cover"
|
||||
cachePolicy="memory-disk" // Use both memory and disk cache
|
||||
transition={200} // Add smooth transition
|
||||
transition={0} // Disable transition to reduce GPU work
|
||||
placeholder={{ blurhash: PLACEHOLDER_BLURHASH } as any}
|
||||
placeholderContentFit="cover"
|
||||
allowDownscaling
|
||||
priority="low" // Deprioritize decode for long lists
|
||||
onLoad={() => {
|
||||
setImageLoaded(true);
|
||||
setImageError(false);
|
||||
|
|
@ -183,7 +184,6 @@ const ContentItem = ({ item, onPress }: ContentItemProps) => {
|
|||
setImageError(true);
|
||||
setImageLoaded(false);
|
||||
}}
|
||||
priority="normal" // Increase priority for better loading
|
||||
recyclingKey={item.id} // Add recycling key for better performance
|
||||
/>
|
||||
) : (
|
||||
|
|
@ -239,11 +239,11 @@ const styles = StyleSheet.create({
|
|||
borderRadius: 12,
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
elevation: Platform.OS === 'android' ? 2 : 0,
|
||||
elevation: Platform.OS === 'android' ? 1 : 0,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 1,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'rgba(255,255,255,0.12)',
|
||||
marginBottom: 8,
|
||||
|
|
|
|||
|
|
@ -157,10 +157,10 @@ const HeroCarousel: React.FC<HeroCarouselProps> = ({ items, loading = false }) =
|
|||
source={{ uri: item.banner || item.poster }}
|
||||
style={styles.backgroundImage as ImageStyle}
|
||||
contentFit="cover"
|
||||
blurRadius={Platform.OS === 'android' ? 12 : 20}
|
||||
blurRadius={Platform.OS === 'android' ? 8 : 12}
|
||||
cachePolicy="memory-disk"
|
||||
transition={200}
|
||||
priority="high"
|
||||
transition={0}
|
||||
priority="low"
|
||||
/>
|
||||
<LinearGradient
|
||||
colors={["rgba(0,0,0,0.45)", "rgba(0,0,0,0.75)"]}
|
||||
|
|
@ -270,7 +270,7 @@ const CarouselCard: React.FC<CarouselCardProps> = memo(({ item, colors, logoFail
|
|||
source={{ uri: item.banner || item.poster }}
|
||||
style={styles.banner as ImageStyle}
|
||||
contentFit="cover"
|
||||
transition={300}
|
||||
transition={0}
|
||||
cachePolicy="memory-disk"
|
||||
/>
|
||||
<LinearGradient
|
||||
|
|
@ -285,7 +285,7 @@ const CarouselCard: React.FC<CarouselCardProps> = memo(({ item, colors, logoFail
|
|||
source={{ uri: item.logo }}
|
||||
style={styles.logo as ImageStyle}
|
||||
contentFit="contain"
|
||||
transition={250}
|
||||
transition={0}
|
||||
cachePolicy="memory-disk"
|
||||
onError={onLogoError}
|
||||
/>
|
||||
|
|
@ -360,11 +360,11 @@ const styles = StyleSheet.create({
|
|||
height: CARD_HEIGHT,
|
||||
borderRadius: 16,
|
||||
overflow: 'hidden',
|
||||
elevation: 6,
|
||||
elevation: 2,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 6 },
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 12,
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 4,
|
||||
},
|
||||
skeletonCard: {
|
||||
width: CARD_WIDTH,
|
||||
|
|
|
|||
|
|
@ -515,8 +515,8 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
clearInterval(progressSaveInterval);
|
||||
}
|
||||
|
||||
// IMMEDIATE SYNC: Reduce sync interval to 5 seconds for near real-time sync
|
||||
const syncInterval = 5000; // 5 seconds for immediate sync
|
||||
// HEATING FIX: Increase sync interval to 15 seconds to reduce CPU load
|
||||
const syncInterval = 15000; // 15 seconds to prevent heating
|
||||
|
||||
const interval = setInterval(() => {
|
||||
saveWatchProgress();
|
||||
|
|
@ -2032,7 +2032,7 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
playWhenInactive={false}
|
||||
ignoreSilentSwitch="ignore"
|
||||
mixWithOthers="inherit"
|
||||
progressUpdateInterval={250}
|
||||
progressUpdateInterval={1000}
|
||||
bufferConfig={{
|
||||
minBufferMs: 15000,
|
||||
maxBufferMs: 50000,
|
||||
|
|
|
|||
|
|
@ -547,8 +547,8 @@ const VideoPlayer: React.FC = () => {
|
|||
clearInterval(progressSaveInterval);
|
||||
}
|
||||
|
||||
// IMMEDIATE SYNC: Reduce sync interval to 5 seconds for near real-time sync
|
||||
const syncInterval = 5000; // 5 seconds for immediate sync
|
||||
// HEATING FIX: Increase sync interval to 15 seconds to reduce CPU load
|
||||
const syncInterval = 15000; // 15 seconds to prevent heating
|
||||
|
||||
const interval = setInterval(() => {
|
||||
saveWatchProgress();
|
||||
|
|
|
|||
|
|
@ -870,8 +870,8 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
|
|||
});
|
||||
};
|
||||
|
||||
// Check completion periodically
|
||||
const completionInterval = setInterval(checkScrapersCompletion, 1000);
|
||||
// Check completion less frequently to reduce CPU load
|
||||
const completionInterval = setInterval(checkScrapersCompletion, 2000);
|
||||
|
||||
// Fallback timeout after 30 seconds
|
||||
const fallbackTimeout = setTimeout(() => {
|
||||
|
|
@ -1039,8 +1039,8 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
|
|||
});
|
||||
};
|
||||
|
||||
// Check completion periodically
|
||||
const episodeCompletionInterval = setInterval(checkEpisodeScrapersCompletion, 1000);
|
||||
// Check completion less frequently to reduce CPU load
|
||||
const episodeCompletionInterval = setInterval(checkEpisodeScrapersCompletion, 2000);
|
||||
|
||||
// Fallback timeout after 30 seconds
|
||||
const episodeFallbackTimeout = setTimeout(() => {
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ export const useMetadataAnimations = (safeAreaTop: number, watchProgress: any) =
|
|||
// Use single progress value for all header animations
|
||||
if (headerProgress.value !== progress) {
|
||||
headerProgress.value = withTiming(progress, {
|
||||
duration: progress ? 200 : 150,
|
||||
duration: progress ? 150 : 100,
|
||||
easing: easings.ultraFast
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ const HomeScreen = () => {
|
|||
let catalogIndex = 0;
|
||||
|
||||
// Limit concurrent catalog loading to prevent overwhelming the system
|
||||
const MAX_CONCURRENT_CATALOGS = 3; // Lower concurrency to reduce CPU/network spikes
|
||||
const MAX_CONCURRENT_CATALOGS = 2; // Very low concurrency to reduce heating
|
||||
let activeCatalogLoads = 0;
|
||||
const catalogQueue: (() => Promise<void>)[] = [];
|
||||
|
||||
|
|
@ -169,8 +169,8 @@ const HomeScreen = () => {
|
|||
activeCatalogLoads++;
|
||||
catalogLoader().finally(async () => {
|
||||
activeCatalogLoads--;
|
||||
// Yield to event loop to avoid JS thread starvation
|
||||
await new Promise(resolve => setTimeout(resolve, 10));
|
||||
// Yield to event loop to avoid JS thread starvation and reduce heating
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
processCatalogQueue(); // Process next in queue
|
||||
});
|
||||
}
|
||||
|
|
@ -605,14 +605,7 @@ const HomeScreen = () => {
|
|||
|
||||
// Add memory cleanup on scroll end
|
||||
const handleScrollEnd = useCallback(() => {
|
||||
// Clear memory cache after scroll settles to free up RAM
|
||||
setTimeout(() => {
|
||||
try {
|
||||
ExpoImage.clearMemoryCache();
|
||||
} catch (error) {
|
||||
// Ignore errors
|
||||
}
|
||||
}, 1000);
|
||||
// No-op; avoid clearing image memory cache here to prevent decode thrash/heating
|
||||
}, []);
|
||||
|
||||
// Memoize individual section components to prevent re-renders
|
||||
|
|
@ -765,7 +758,6 @@ const HomeScreen = () => {
|
|||
showsVerticalScrollIndicator={false}
|
||||
ListHeaderComponent={memoizedHeader}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
onMomentumScrollEnd={handleScrollEnd}
|
||||
onEndReached={handleLoadMoreCatalogs}
|
||||
onEndReachedThreshold={0.6}
|
||||
scrollEventThrottle={32}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ class ImageCacheService {
|
|||
private cleanupInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor() {
|
||||
// Start cleanup interval every 10 minutes
|
||||
// Start cleanup interval every 30 minutes (less churn)
|
||||
this.cleanupInterval = setInterval(() => {
|
||||
this.performCleanup();
|
||||
}, 10 * 60 * 1000);
|
||||
}, 30 * 60 * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -40,13 +40,13 @@ class ImageCacheService {
|
|||
// Update access tracking
|
||||
cached.accessCount++;
|
||||
cached.lastAccessed = Date.now();
|
||||
logger.log(`[ImageCache] Retrieved from cache: ${originalUrl.substring(0, 50)}...`);
|
||||
// Skip verbose logging to reduce CPU load
|
||||
return cached.localPath;
|
||||
}
|
||||
|
||||
// Check memory pressure before adding new entries (more lenient)
|
||||
if (this.cache.size >= this.MAX_CACHE_SIZE * 0.95) {
|
||||
logger.log(`[ImageCache] Skipping cache due to size limit`);
|
||||
// Skip verbose logging to reduce CPU load
|
||||
return originalUrl;
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ class ImageCacheService {
|
|||
this.currentMemoryUsage += estimatedSize;
|
||||
this.enforceMemoryLimits();
|
||||
|
||||
logger.log(`[ImageCache] ✅ NEW CACHE ENTRY: ${originalUrl.substring(0, 50)}... (Cache: ${this.cache.size}/${this.MAX_CACHE_SIZE}, Memory: ${(this.currentMemoryUsage / 1024 / 1024).toFixed(1)}MB)`);
|
||||
// Skip verbose logging to reduce CPU load
|
||||
return cachedImage.localPath;
|
||||
} catch (error) {
|
||||
logger.error('[ImageCache] Failed to cache image:', error);
|
||||
|
|
@ -231,12 +231,7 @@ class ImageCacheService {
|
|||
this.enforceMemoryLimits();
|
||||
this.enforceMaxCacheSize();
|
||||
|
||||
// Clear Expo image memory cache periodically
|
||||
try {
|
||||
ExpoImage.clearMemoryCache();
|
||||
} catch (error) {
|
||||
// Ignore errors from clearing memory cache
|
||||
}
|
||||
// Avoid clearing Expo's global memory cache to prevent re-decode churn
|
||||
|
||||
const finalSize = this.cache.size;
|
||||
const finalMemory = this.currentMemoryUsage;
|
||||
|
|
|
|||
Loading…
Reference in a new issue