読者です 読者をやめる 読者になる 読者になる

taiki-t's diary

あいうえお

React Nativeの画像キャッシュ

Tips React Native

プロローグ

React Native使ってみた。Imageコンポーネント、毎回ネットワークから取得してるじゃん、これキャッシュしてくれないの?と思った。

調べた

[0.32] Image caching broken · Issue #9581 · facebook/react-native · GitHub

なんか壊れてんヨーという報告を発見。やっぱ壊れてんのかと思いつつ。 でもキャッシュしてもらえる人ともらえない人がいるみたい。日頃のおこない? ちなみに俺はキャッシュしてもらえてない。バージョンは0.38.0で。

なんでやねんと色々思っていると、画像サイズが大きいとダメだというコメントが目に入る。 画像サイズを小さくして試してみる。いけた。600KB -> 178kBぐらいに絞った。

どうやらReact Nativeは画像の取得にiOSに元からあるNSURLRequestという仕組み使っていて、そのNSURLRequestNSURLCacheさらにはNSURLSessionとやらの仕様にしたがってキャッシュを行うらしい。

そしてこのNSURLSessionは指定した上限の、5%までのファイルサイズしかキャッシュしないみたい。

で、React Nativeはどれほど指定しているのかなーと思ったら

  _decodedImageCache.totalCostLimit = 5 * 1024 * 1024; // 5MB

なるほど600KBはキャッシュされないですねと。てか上限小さすぎない?そしてそもそも

static const NSUInteger RCTMaxCachableDecodedImageSizeInBytes = 1048576; // 1MB

1MB以上のファイルはRN側でキャッシュしないように指定してるみたい。参照したのはここらへんhttps://github.com/facebook/react-native/blob/v0.38.0/Libraries/Image/RCTImageCache.m#L23

まぁただここらへんの挙動は変数名から推測した程度なので、自信はない。

TL;DR

画像サイズが大きいとダメみたい。250KB以下にした方が良さげ。 Imageコンポーネント、キャッシュしてくれる。シミュレーターでも動作が怪しいかもしれない。実機で動かしたらちゃんとキャッシュしてくれてた。

参考リンク

[0.32] Image caching broken · Issue #9581 · facebook/react-native · GitHub

Change RCTImageLoader's Cache System to default NSURLRequest's cache … · facebook/react-native@631785f · GitHub

https://github.com/facebook/react-native/blob/v0.38.0/Libraries/Image/RCTImageCache.m

URLSession:dataTask:willCacheResponse:completionHandler: - NSURLSessionDataDelegate | Apple Developer Documentation

ios - How to cache using NSURLSession and NSURLCache. Not working - Stack Overflow