🚀

画像の読み込み速度を上げたい!-cached_network_image-

2024/02/17に公開

こんにちは

現役で美容師をやりつつフルタイムでflutterエンジニアをしている中岡です。
自己発信&備忘録として残していきます!

解決したい問題

画像の読み込み速度を上げたい!!

画像を複数取り扱うようなアプリの場合、画像のロードの遅延に悩むことが多いと思います。
こちらを解決していきます!

結果

簡単かつかなり遅延がなくなりました。
こちらの僕のアプリの動画を見てください!

上のshampoo一覧が導入後の速度
下のtreatmen一覧が導入前の速度になります。

全然違いますよね!!
※1回目はキャッシュされていない為、普通の読み込み速度になります。

方法

こちらのcached_network_imageパッケージを使うだけです。
https://pub.dev/packages/cached_network_image/install

しかも簡単で
Image.networkCachedNetworkImageに変換するだけです。
${shampoo[index].imgURL} は僕の場合はfireStoreに保存してあるpathを入れてます。

+ CachedNetworkImage(
+   imageUrl: '${shampoo[index].imgURL}',
+   fit: BoxFit.cover,
+   errorWidget: (context, url, error) => Icon(Icons.error),
+ ),

- Image.network(
-   '${shampoo[index].imgURL}',
-   fit: BoxFit.cover,
- ),

ロード中にインジケータを設定したい人はこちらを追加するだけです。

progressIndicatorBuilder: (context, url, downloadProgress) => 
               CircularProgressIndicator(value: downloadProgress.progress),

詳しく知りたい方向け

こちらはよりパッケージの中身を知りたい方向けです。
パッケージの理解に参考にさせて頂いた記事を貼らせていただきます。
一旦アプリを早く作りたい方は見なくても良いかもしれません。
抜粋してみてほしいところをタイトルに書いております。

キャッシュの理解とテスト方法について

https://zenn.dev/flutteruniv_dev/articles/20220615-160504-flutter-cached-network-image-test#cachemanager-をモック化する

備忘録

path_provider は、
保管場所のパスを提供し、保存先を決定するのに必要。

file パッケージは、
ファイルの読み書きや管理など、ファイルシステム上の操作を行うために必要。

sqflite は、
ファイルに関するメタデータ(保存場所、ダウンロードした日時、ファイルサイズなど)を保存するのに必要。ないと保存した場所がわからなくなって読み込めなくなる。
カスタマイズができなくなる

なので大きくこの3つのパッケージから成り立っている。
これを理解するとこちらの記事が生きてきます。

何故保存先が変更できるのか?

https://zenn.dev/team_soda/articles/dad8114d6ce515#isar用のcacheinforepositoryの作成

備忘録

sqfliteはDBとして使用してるイメージになります。
なので、そこを変更してあげることによって自分のやりたいように情報の保存先が変更ができるということ!

そして、path_provider と file を使用しているということはこのようなことも可能になります。

iOS の Files に表示させる

https://zenn.dev/pressedkonbu/articles/flutter-file-io

備忘録

....と思いましたがこれはできませんでした(笑)
理由は、 上記の記事は、Application Documents Directory に保存しています。
こちらは、外部から受付可能なディレクトリに対して、
cached_network_imageはApplication Support Directory に保存しているためです。
これは外部から受け付けられないディレクトリです!
なので、表示はできなかったのです。

コードはこの部分になるかと思います。

CacheObjectProvider

  Future<String> _getPath() async {
    Directory directory;
    if (_path != null) {
      directory = File(_path!).parent;
    } else {
      // こちらの部分です↓
      directory = await getApplicationSupportDirectory();
    }
    await directory.create(recursive: true);
    if (_path == null || !_path!.endsWith('.db')) {
      _path = join(directory.path, '$databaseName.db');
    }
    await _migrateOldDbPath(_path!);
    return _path!;
  }

保存先について

こちらの記事がわかりやすかったです。

https://zenn.dev/beeeyan/articles/b9f1b42de9cb67

最後に

実装自体簡単ですが、ついつい深くまで見ていってしまうと止まらないので
今回はこんな感じで終わりにしたいと思います。

まだ遅延が気になる方下記を参考にしてもいいかもしれません。
僕は問題なくなった為しておりません。
https://flutter.salon/flutter/deferfirstframe-precacheimage/

僕の作っている
オリジナルのカスタマイズシャンプーセットが作れるアプリ
よかったら是非触ってみてください!!

リンクはこちらです。
https://apps.apple.com/jp/app/カスタマイズシャンプーを作るならケアマネ/id6450120757

https://play.google.com/store/apps/details?id=com.railway.keamane&hl=en_SG

ありがとうございました。

Discussion