From 049f565ff9b3ad4ce1235327142862be9a64af87 Mon Sep 17 00:00:00 2001 From: SH20RAJ Date: Fri, 19 Sep 2025 20:11:57 +0530 Subject: [PATCH] fix: eliminate tap delay when opening image lightbox Fixes #9049 - Remove InteractionManager.runAfterInteractions() from image onPressIn handler which was causing 1+ second delay before opening lightbox - Add immediate prefetching on component mount for better responsiveness - Switch lightbox animations from SLOW_SPRING to FAST_SPRING for snappier feel - Images now open instantly on tap instead of hanging for 1+ seconds The issue was particularly noticeable on posts with multiple images where InteractionManager would wait for all pending interactions to complete before prefetching, causing significant user-perceived delay. --- src/components/Post/Embed/ImageEmbed.tsx | 32 ++++++++++++++------ src/view/com/lightbox/ImageViewing/index.tsx | 10 ++---- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/components/Post/Embed/ImageEmbed.tsx b/src/components/Post/Embed/ImageEmbed.tsx index 4ed17230e53..12e339f0a14 100644 --- a/src/components/Post/Embed/ImageEmbed.tsx +++ b/src/components/Post/Embed/ImageEmbed.tsx @@ -1,4 +1,5 @@ -import {InteractionManager, View} from 'react-native' +import React from 'react' +import {View} from 'react-native' import { type AnimatedRef, measure, @@ -26,13 +27,25 @@ export function ImageEmbed({ const {openLightbox} = useLightboxControls() const {images} = embed.view + const items = React.useMemo( + () => + images.map(img => ({ + uri: img.fullsize, + thumbUri: img.thumb, + alt: img.alt, + dimensions: img.aspectRatio ?? null, + })), + [images], + ) + + // Prefetch full-size images on component mount for better responsiveness + React.useEffect(() => { + if (images.length > 0) { + Image.prefetch(items.map(i => i.uri)) + } + }, [items, images.length]) + if (images.length > 0) { - const items = images.map(img => ({ - uri: img.fullsize, - thumbUri: img.thumb, - alt: img.alt, - dimensions: img.aspectRatio ?? null, - })) const _openLightbox = ( index: number, thumbRects: (MeasuredDimensions | null)[], @@ -63,9 +76,8 @@ export function ImageEmbed({ })() } const onPressIn = (_: number) => { - InteractionManager.runAfterInteractions(() => { - Image.prefetch(items.map(i => i.uri)) - }) + // Remove InteractionManager to eliminate delay and prefetch immediately + Image.prefetch(items.map(i => i.uri)) } if (images.length === 1) { diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index bb3c39f5940..e7a9a6a7751 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -57,12 +57,6 @@ type Rect = {x: number; y: number; width: number; height: number} const PORTRAIT_UP = ScreenOrientation.OrientationLock.PORTRAIT_UP const PIXEL_RATIO = PixelRatio.get() -const SLOW_SPRING: WithSpringConfig = { - mass: isIOS ? 1.25 : 0.75, - damping: 300, - stiffness: 800, - restDisplacementThreshold: 0.01, -} const FAST_SPRING: WithSpringConfig = { mass: isIOS ? 1.25 : 0.75, damping: 150, @@ -112,14 +106,14 @@ export default function ImageViewRoot({ // https://github.com/software-mansion/react-native-reanimated/issues/6677 rAF_FIXED(() => { openProgress.set(() => - isAnimated ? withClampedSpring(1, SLOW_SPRING) : 1, + isAnimated ? withClampedSpring(1, FAST_SPRING) : 1, ) }) return () => { // https://github.com/software-mansion/react-native-reanimated/issues/6677 rAF_FIXED(() => { openProgress.set(() => - isAnimated ? withClampedSpring(0, SLOW_SPRING) : 0, + isAnimated ? withClampedSpring(0, FAST_SPRING) : 0, ) }) }