0

thanks for taking the time to help!

I am building an app that displays many images/GIFs. I have been using CachedNetworkImage to display these assets. I noticed today that my app cache on both iOS and Android were larger than expected (500MB on iOS and 1GB on Android).

I did some investigating and found that there were thousands of cached GIFs/jpgs under libCachedImageData and that many of the files haven't been accessed for over 30 days.

I was under the assumption that CachedNetworkImage's default cache only keeps things around for 30 days and up to 200MB. Am I missing a step to make sure the cache is properly cleaned up?

Thank you!

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:tabler_icons/tabler_icons.dart';

class OptimizedCachedImage extends StatelessWidget {
  final String imageUrl;
  final double? width;
  final double? height;
  final BoxFit? fit;
  final Widget Function(BuildContext, String)? placeholder;
  final Widget Function(BuildContext, String, Object)? errorWidget;
  final ProgressIndicatorBuilder? progressIndicatorBuilder;

  const OptimizedCachedImage({
    super.key,
    required this.imageUrl,
    this.width,
    this.height,
    this.fit,
    this.placeholder,
    this.errorWidget,
    this.progressIndicatorBuilder,
  });

  @override
  Widget build(BuildContext context) {
    final pixelRatio = MediaQuery.of(context).devicePixelRatio;
    final finalWidth = width != null ? width! * pixelRatio : null;
    final finalHeight = height != null ? height! * pixelRatio : null;

    return CachedNetworkImage(
      cacheKey: '$imageUrl-${finalWidth?.round()}x${finalHeight?.round()}',
      imageUrl: imageUrl,
      width: width,
      height: height,
      fit: fit,
      memCacheWidth: finalWidth?.round(),
      memCacheHeight: finalHeight?.round(),
      maxWidthDiskCache: finalWidth?.round(),
      maxHeightDiskCache: finalHeight?.round(),
      placeholder: placeholder,
      errorWidget: errorWidget ??
          (context, url, error) => const Icon(TablerIcons.file_broken),
      progressIndicatorBuilder: progressIndicatorBuilder,
    );
  }
}
2
  • CachedNetworkImage uses flutter_cache_manager. You can create a custom configuration to control it and use it in the constructor of CachedNetworkImage with parameter cacheManager. Commented Mar 25 at 23:31
  • Thanks @PeterKoltai! I tried to do that but for some reason, things that were cached previously were failing to load. I also found this issue, which makes me think this might be a bug in Flutter Cache Manager. github.com/Baseflow/flutter_cache_manager/issues/476 Commented Mar 26 at 21:05

1 Answer 1

0

Make custom fn:

import 'package:flutter_cache_manager/flutter_cache_manager.dart';

class CustomCacheManager {
  static const key = 'customCacheKey';
  static final instance = CacheManager(
    Config(
      key,
      stalePeriod: const Duration(days: 7), // Keep files for 7 days
      maxNrOfCacheObjects: 100, // Limit to 100 files
    ),
  );
}

Use in your code:

class OptimizedCachedImage extends StatelessWidget {
  final String imageUrl;
  final double? width;
  final double? height;
  final BoxFit? fit;
  final Widget Function(BuildContext, String)? placeholder;
  final Widget Function(BuildContext, String, Object)? errorWidget;
  final ProgressIndicatorBuilder? progressIndicatorBuilder;

  const OptimizedCachedImage({
    super.key,
    required this.imageUrl,
    this.width,
    this.height,
    this.fit,
    this.placeholder,
    this.errorWidget,
    this.progressIndicatorBuilder,
  });

  @override
  Widget build(BuildContext context) {
    final pixelRatio = MediaQuery.of(context).devicePixelRatio;
    final finalWidth = width != null ? width! * pixelRatio : null;
    final finalHeight = height != null ? height! * pixelRatio : null;

    return CachedNetworkImage(
      cacheManager: CustomCacheManager.instance, // Use custom manager
      cacheKey: '$imageUrl-${finalWidth?.round()}x${finalHeight?.round()}',
      imageUrl: imageUrl,
      width: width,
      height: height,
      fit: fit,
      memCacheWidth: finalWidth?.round(),
      memCacheHeight: finalHeight?.round(),
      maxWidthDiskCache: finalWidth?.round(),
      maxHeightDiskCache: finalHeight?.round(),
      placeholder: placeholder,
      errorWidget: errorWidget ??
          (context, url, error) => const Icon(TablerIcons.file_broken),
      progressIndicatorBuilder: progressIndicatorBuilder,
    );
  }
}

// Manually Trigger Cleanup (Optional):

await CustomCacheManager.instance.emptyCache(); //clear entire cache

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I tried to do that but for some reason, things that were cached previously were failing to load. I also found this issue, which makes me think this might be a bug in Flutter Cache Manager so even using a custom manager will have this issue. github.com/Baseflow/flutter_cache_manager/issues/476

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.