-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[0.32] Image caching broken #9581
Comments
@sjmueller, any help would be welcome. |
@sjmueller, I looked into the caching and the image cache is being hit. My diffs did not change the implementation, rather separated the cache from the loader. What I suspect may be causing the issue would be the fetchDate being part of the cacheKey. This was added in 631785f, @javache may be able to provide some more context. |
@sjmueller: can you provide an example of an image (URL) that fails to be cached? |
It would be really nice to understand how image caching works in RN and how one could leverage the nuances of the code. The cache behavior/logic is documented somewhere? |
any progress? seems the images are only cached in several seconds, and then need new fetch |
React Native for iOS does not implement its own network caching for images. Instead we rely on the system's default NSURLCache (see http://nshipster.com/nsurlcache/ for details). If your images are refetched continuously, this may point to a misconfiguration of the cache headers sent by your server. |
@javache, I'm maintaining a react-native photo library component and I've been experiencing cache problem since version 0.25. I tested the problem a lot and I see that's happening when I create jsbundle file with react-native bundler and embed it within the app. Cache is working fine when I serve jsbundle from my computer. Here is the Github issue for the problem: halilb/react-native-photo-browser#8 I've used some Flickr images for this test and I can also confirm http responses have valid cache headers. @sjmueller Can you check my issue to see if it seems relevant with yours? |
I started seeing caching problems when upgrading from 0.30 to 0.32. Looked like images reloaded every time. Reverted back to 0.30 |
I'm seeing this as well. My packager is echoing the same images over and over (which is new to 0.32 vs 0.31)
|
I'm trying to reproduce a crash that happens when I toggle images, unfortunately I was not able to reproduce the crash, but here's basically what I'm trying to do: https://github.com/rclai/react-native-image-caching-problem My original problem is that if I toggle the images without the style attribute, it's fine, but once I introduce the style tag, I get a crash that looks like this:
|
Looking at this because I was seeing the same static local asset being fetched over and over from the packager server like @chrisnojima, I found out that this specific behavior was introduced by 631785f As @javache was saying, React Native is relying on the system's default NSURLCache. However the packager is not setting any cache headers for assets requests. Hence in development, everytime a local asset is needed it's fetched again from the packager server. Adding a |
Does this happen with remote images (http://, https://) or with local assets stored in the filesystem that are part of the app? @sjmueller I understand this happens in release mode, with the packager not running, correct? |
I recently have reported multiple issues to NSUrlSession caching in iOS:
|
I encountered this bug too. Images are being refetched on every component mount. It doesn't matter if you set caching headers, it omits caching completely. This is happening only with remote images, as far as I can tell, and it is happening in both development and release mode. I'm using RN 0.32.1 on iOS only. |
This is happening to my local assets as well. To be more specific, local as in images inside a folder in my JS code, not |
Having this issue on 0.33.0 in release mode when loading remote images. Every time the component renders it reloads the images. Have a simple ListView with image thumbnails. Downgrading to 0.30.0 "fixes" the issue. |
@bsiddiqui I downgraded to react-native@0.30.0 but this did not seem to solve my issue. Remote images still did not fetch from cache; they are still being loaded from the url. Just an fyi for anyone else attempting to downgrade to resolve this issue, perhaps downgrading further down would do it? |
@bestander here's a video of the issue (think it's the same issue) 0.32.1 - see how images flash when ListView re-renders 0.31.0 - and previous versions did not have this issue |
Thanks a lot, guys, we hear you. There are 182 commits between 0.31 and 0.32: 0.31-stable...0.32-stable |
@bsiddiqui Can you please link the URL of the images you're trying to load? After 631785f we now respect the cache-control headers sent by the server, so if the server is not marking this image as cacheable, we need to refetch it. |
Experiencing the same with RN 0.33 |
@javache https://ramble.s3.amazonaws.com/uploads/5f314937-7041-462a-ae4a-34d4435382a1
My image is set with // Setting key to uri so that it updates properly
// https://github.com/facebook/react-native/issues/1417
<Image key={uri} source{{ uri }} /> Perhaps this is a different problem. If I remove the key it doesn't flash but the images seem to re-render a couple seconds after the rest of the list: https://www.dropbox.com/s/8nsqe3mg7jh28cv/imageswap.mov?dl=0 |
@bsiddiqui, we have a fix in master branch now #9795 for dev mode. |
@bestander just tested on master and same issue is happening: https://www.dropbox.com/s/3a7uj2phwhb7rgv/rnmaster.mov?dl=0 You can see the flash on the simulator on the right. Using master. |
Anyone observing this in RN 34 / 35RC? |
Yes I'm still getting this even after deleting all node modules and reinstalling. In on 0.34.0. |
@bestander @jeveloper not having the issue anymore in 0.34.0 |
as @pieterdb said earlier, the default React image cacher uses NSURLCache for the url request. Can someone who is running into this issue set some breakpoints in RCTImageCache.m when calling RCTCacheKeyForImage and tell us what they're seeing |
Same issue here in RN 0.40 fetching remote images. HTTP/1.1 200 OK |
Summary: Hi, This PR fixes the problem described by chrisnojima in facebook/react-native#9581 (comment) **Test plan** In development mode, - Run an app with an image: `<Image source={ require('./logo.png') }/>` - Notice that you see the following in packager console: ```txt 6:46:42 PM] <START> processing asset request logo.png [6:46:42 PM] <END> processing asset request logo.png (1ms) ``` - Reload the app, or navigate to another page of the app with the same image - Notice that you see again: ```txt 6:47:23 PM] <START> processing asset request logo.png [6:47:23 PM] <END> processing asset request logo.png (1ms) ``` Now wih the fix applied, notice that you only see `logo.png` fetched once, even if you reload or show the same image in a different part of the app. Let me know what you think. Closes facebook/react-native#9795 Differential Revision: D3876945 Pulled By: davidaurelio fbshipit-source-id: f41f4719e87644692a690123fd6e54eead9cc87d
I'm having this issue with RN 0.40. Debugging I found that with small images: cacheKey in |
Seems to be fixed for me in 0.41.2 |
Debugging into this, it seems the problem is related to these lines.
The solution is to just use a bigger cache here instead of the default one. Initially I thought we would need to expose the cache size to be configurable, and in the aforementioned lines use that size configuration. But if I'm not mistaken, the NSURLCache.sharedURLCache = [[NSURLCache alloc] initWithMemoryCapacity: 4 * 1024 * 1024
diskCapacity: 20 * 1024 * 1024
diskPath: nil]; inside For us, this started caching large enough images as we needed. |
I'm experiencing this issue as well. I'm testing by going back and forth between two different routes in my application, with one of these routes loading an Image component. The effect of navigating between the two routes is that the component that contains the Image component is mounted/unmounted on each route change. Every time I go to the route containing the Image, the actual jpeg image is being fully reloaded, rather than being cached after the first load and then loaded from the cache after that. For reference, the image I'm testing this with is https://images.pexels.com/photos/73763/rugby-sports-players-competition-73763.jpeg?w=8192, which is a 6.6MB image that has the following response headers:
I believe these response headers should result in the image being cached, as the response headers are indicating that the image should be cached for 1 year. I tried the solution @raulmt posted, but this did not seem to have any effect. I also tried increasing the amounts like so:
This also did not seem to have any effect. I'm not doing anything fancy with the Image component, it looks like the following:
I'm using the following dependencies:
|
We think we are seeing this also with 0.40 on iOS, Android is unaffected. Has anyone had a chance to see if the changes for caching updates in 0.42 (https://facebook.github.io/react-native/docs/images.html#cache-control-ios-only) have improved anything? |
We use different Image and caching modules internally - this would be a nice opportunity for someone in the community to tackle. Maybe @janicduplessis? Sounds like there are a lot of karma points to be earned :) |
I've been using a custom Image module on iOS that is a simple wrapper around https://github.com/rs/SDWebImage since I've had issues with flickers and caching with the current implementation. Leveraging an existing image library seemed like an easier solution for me than trying to fix our current implementation. If this would make sense for RN to use this instead of our current implementation I could work on cleaning it up and upstreaming it. I think image loading is really complex and makes sense to leverage an external library a bit like Android does with Fresco, especially considering the iOS implementation is more or less maintained since it is not used in FB apps. |
@brentvatne / @ide : what does exponent do? Would be nice to fix this by default in the core rather than using an external plugin. |
@sahrens It uses the core one. I guess the main changes that would be needed to make the current implementation have better UX is
Number 2 is probably the hardest to get right since it may differ depending on the app usage of images. One thing that the current implementation does that causes issues for one of my use cases is it caches a resized version of the image in memory instead of the original which causes flickers when loading the same image with different sizes. It should probably be customizable from objc. |
@janicduplessis I am thinking of using SDWebImage/wrapper for our app. Do you think building an animated version of wrapper for SDWebImage would be complicated? |
I can confirm that in RN 0.44 cached images in iOS are not working, using "force-cache" simply reloads from URL and using "only-if-cached" does not load the images at all, despite the images having been loaded previously using the same url. |
Same issue on 0.44 image still not cached. It request every mount of component. |
Are there any updates on this? Will this be fixed / investigated or should we go with external libraries to achieve reliable caching? |
I'm using 0.46 and it is not caching right, if needed I can provide image urls that does cache on chrome but not in react native. |
Looks like it caches some small image but not big ones (my 200K images are cached but the 8m ones are not) |
There is a limit for store the image based on his size. Check this file for more information: |
@samouss Hey, thanks so much for point me to that code! |
@samouss It looks like it has a cap of 1mb. However, even if I downgrade my images to 550kb it still wouldn't cache it. It is using |
Yes you are right. But if you upload the Image from your app you can crop it for reduce his size with the ImageEditor API. Or do it on the server to avoid too large image. I don't see any other solutions for now. Maybe in future release the caching strategy will be more performant as mentioned in this thread and you can upvote for this feature on Canny. |
It looks like this is only happening on iOS, for Android it is working perfectly. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions. |
There has been quite a noticeable regression with image caching in 0.31. The symptoms in my app are that any image rendered multiple times is fetched (and re-decoded?) for each Image instance. This is especially apparent with small avatar images, which in the past would have no delay in appearing if the same one was rendered in in a previous Image component.
The symptoms can be observed on iOS; both simulator and device, in both debug and release mode; I have not checked on Android, and have not tested with 0.33 rc. I can create a video to illustrate the problem, but currently traveling to London and won't be able until I return back to the states next week.
I suspect it has to do with the significant image cache refactor that happened on these commits: f12d0a2 54244e1 ddc70ff
I originally mentioned #9431 but here we can track the issue separately.
cc @bestander @mkonicek @javache
Would like to cc Maria Mateescu (author on all three commits above) but don't actually know her github handle. Maybe @matemariaescu ?
The text was updated successfully, but these errors were encountered: