- Replace Brush.horizontalGradient/verticalGradient with 1px ImageBitmap rendered via android.graphics.LinearGradient in MetaDetailsScreen and StreamScreen - GPU does a single texture sample per pixel instead of computing gradient per frame
- Remove leftGradient and dimColor overlays from BackdropLayer
- Restore focusedScale from 1.0 to 1.02 on season tabs and episode cards
- Replace deprecated focusRestorer(lambda) with focusRestorer(FocusRequester)
- Replace deprecated Divider with HorizontalDivider
EpisodesSection:
- Set focusedScale=1.0f on EpisodeCard and SeasonTabs to eliminate
graphicsLayer offscreen buffers created by TV Material3 scale animation
- Explicitly set glow=CardDefaults.glow() on EpisodeCard to disable
shadow GPU pass
- Remove always-visible semi-transparent border (White 14%) from EpisodeCard
- Fix inline NuvioColors reads: hoist Primary/TextPrimary/TextSecondary/FocusRing
before remember blocks and drawWithCache
- Use episode.id as remember key for lambdas instead of full episode object
- Wrap progress/imdbRating/isMarkedWatched in remember to avoid map lookups per frame
- Cache episodeOnFocusRestored in remember instead of inline lambda
MetaDetailsScreen:
- Add noVerticalScrollResponder (BringIntoViewResponder with no-op
bringChildIntoView) on SeasonTabs and EpisodesRow items to prevent
LazyColumn from triggering full vertical re-layout on every horizontal
focus movement inside nested LazyRows
- cache all TextStyle.copy() calls in remember (episodeBadgeStyle, titleStyle,
descriptionStyle, metaLabelStyle, ratingStyle) - was allocating new TextStyle
on every recomposition per card
- cache Color.copy() calls in remember (badgeBgColor, progressBgColor)
- remove redundant .clip(shape) from inner Box - Card already clips via CardDefaults.shape
- replace 2x Box+clip progress bar with single drawWithCache drawRoundRect - eliminates
two saveLayer calls per card per frame
EpisodesSection:
- replace animateFloatAsState (overlay alpha) with direct value
- hoist imdbLogoRequest from per-card to EpisodesRow level
- wrap getOrPut in remember(episode.id) to prevent map mutation during composition
- wrap dashPathEffect in remember to avoid per-draw allocation
CastSection / MoreLikeThisSection / CollectionSection:
- wrap getOrPut in remember(key) to prevent map mutation during composition
MetaDetailsScreen:
- extract BackdropLayer composable to isolate animateFloatAsState from LazyColumn scope
- replace 3x Box+graphicsLayer gradient overlays with single drawWithCache pass
- read gradient alphas as State.value inside onDrawBehind to skip recomposition on alpha change