Skip to content

fix: discard stale Image loads for recycled/re-bound views - #167

Open
mrousavy wants to merge 1 commit into
mainfrom
fix/cancel-stale-image-loads
Open

mrousavy wants to merge 1 commit into
mainfrom
fix/cancel-stale-image-loads

Conversation

@mrousavy

Copy link
Copy Markdown
Owner

HybridImageLoader.requestImage(forView:) kicked off an async load and then unconditionally assigned the result to the view's imageView, with no cancellation and no way to tell whether that result was still wanted.

In a list, that means:

  1. Cell A starts loading image A into view V.
  2. V is recycled and re-bound to cell B, showing image B.
  3. Load A resolves and overwrites V with image A.

prepareForRecycle() clearing the image doesn't help, because it runs before the stale completion lands. The same happens without recycling whenever the image prop changes mid-load and the two loads resolve out of order (easy to hit, since a cached HybridImageLoader resolves instantly while an uncached one doesn't).

This adds a monotonic per-view request token:

  • beginImageRequest() starts a request and invalidates any in-flight one
  • cancelImageRequest() invalidates without starting a new one (called from dropImage)
  • isImageRequestValid(token) is checked right before the result is applied

On iOS this is exposed as a new ImageRequestTracking protocol next to NativeImageView, so third-party image views can opt into it. Views that don't conform keep working exactly as before, they just don't get cancellation.

react-native-nitro-web-image is unaffected - SDWebImage and Coil already scope requests to the target view.

Testing

Not verified on device - CI builds cover compilation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant