Flutterで、なるはやで画像をキャッシュする

Flutterで画像を遅延少なく表示するために事前に読み込む機能 precacheImage がある。使用したので、メモを残します。

追記(2025/04/06):

  • binding.renderViewElementが 非推奨になったので、binding.rootElementに変更
  • PaintingBinding.instance.imageCache について記載
  • cacheWidth, cacheHeightについて記載

アプリ起動時に読み込む

void main() async {

  final binding = WidgetsFlutterBinding.ensureInitialized();

  binding.addPostFrameCallback((_) async {
    final Element? context = binding.rootElement;

    List images = [
      const AssetImage('assets/images/test.jpg'),
      const NetworkImage(
        'https://flutter.salon/wp-content/uploads/2022/03/IMGP7858-768x508.jpg',
      )
    ];

    for (final image in images) {
      precacheImage(
        image,
        context,
      );
    }
  });

  runApp(
    MyApp(),
  );
}

画面単位で読み込む

画面が表示されたときにすぐに表示したい場合は、didChangeDependenciesで実施する(initStateではcontextができていない)

import 'package:flutter/material.dart';

class PrecachTest extends StatefulWidget {
  const PrecachTest({Key? key}) : super(key: key);

  @override
  State createState() => _PrecachTestState();
}

class _PrecachTestState extends State {
  List images = [
    const AssetImage('assets/images/test.jpg'),
    const NetworkImage(
      'https://flutter.salon/wp-content/uploads/2022/03/IMGP7858-768x508.jpg',
    )
  ];
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void didChangeDependencies() {
    for (var image in images) {
      precacheImage(image, context);
    }
    super.didChangeDependencies();
  }
}

キャッシュの上限を設定する

Flutterでは画像キャッシュの最大数や最大容量を指定することができます。キャッシュ数が多すぎるとメモリを圧迫するため、制限を設けることでパフォーマンスの最適化が可能です。

PaintingBinding.instance.imageCacheを用いて、キャッシュの上限をbuild内で設定できます。

 PaintingBinding.instance.imageCache
  ..maximumSize = 100 // 最大100個までキャッシュ
  ..maximumSizeBytes = 50 * 1024 * 1024; // 最大50MBまでキャッシュ
 

キャッシュする画像サイズを指定する

画像サイズが大きすぎると、キャッシュも大きくなりメモリ使用量が増加します。Image.networkなどで画像を表示する際にcacheWidthcacheHeightを指定することで、縮小された画像がキャッシュされ、効率的なメモリ使用が可能になります。

 Image.network( imageUrl, cacheWidth: 300, cacheHeight: 200, )  

参考