Baseflow / flutter_cache_manager

Generic cache manager for flutter
https://baseflow.com
MIT License
740 stars 429 forks source link

(willing to make a PR) remove dependency on package:image to make it run faster and make app size smaller by 300KB (compressed) #310

Closed fzyzcjy closed 3 years ago

fzyzcjy commented 3 years ago

šŸ› Bug Report

Expected behavior

Thanks for the wonderful lib! However, it has dependency on package:image, which results in at least 300KB (compressed) size in the final APK file. As we all know, size of final app is very important - bigger app size will lead to less downloads.

IMHO the lib is only used here: https://github.com/Baseflow/flutter_cache_manager/blob/master/flutter_cache_manager/lib/src/cache_managers/image_cache_manager.dart#L75 But indeed, we can use a pure-flutter way to solve this problem! See this: https://stackoverflow.com/questions/44665955/how-do-i-determine-the-width-and-height-of-an-image-in-flutter. If need more info I am willing to help or make a PR.

In addition, in a more abstract level, Flutter already included image codecs (otherwise we cannot see those images using Image widget!). So if the package:image is used, then the image codecs are included twice in a final apk - which is definitely a waste of space.

Last but not least, if we use package:image, the speed will be slower than using the function that Flutter provides - since pure-dart is always kind of slower than native C++ code.

Reproduction steps

just use the package, and analyze the final released apk file

Configuration

Version: latest

Platform:

renefloor commented 3 years ago

Hi, The image library is mainly used to resize the image here: https://github.com/Baseflow/flutter_cache_manager/blob/master/flutter_cache_manager/lib/src/cache_managers/image_cache_manager.dart#L85

If you would know a better way to do that it would be really great, because that resize function seems to be quite slow and blocking the UI thread.

fzyzcjy commented 3 years ago

@renefloor What about this approach: Use this way to decode the image. At the same time, do not use the raw MemoryImage (or things like DiskImage), but instead, use ResizeImage(MemoryImage(bytes), width: 50, height: 100).

IMHO this should work! And this should be very fast, because everybody uses this in Flutter. If I remembered correctly, it may even use GPU to do some acceleration if possible.

As another advantage, now we do not need to decode the original image! If the original image is huge, that wasted decoding will also be slow.

In other words:

final image = ResizeImage(Image.network('https://i.stack.imgur.com/lkd0a.png', width: THE_RESIZED_WIDTH, height: THE_RESIZED_HEIGHT);
final completer = Completer<ui.Image>();
image.image
      .resolve(new ImageConfiguration())
      .addListener(ImageStreamListener(ImageInfo info, bool _) { 
        completer.complete(info.image));
      })

// then use that completer.future as normal
renefloor commented 3 years ago

Hmm that might be an option indeed, I'll give it a try.

fzyzcjy commented 3 years ago

@renefloor šŸŽ‰ Looking forward to it!

fzyzcjy commented 3 years ago

@renefloor Hi is there any updates?

renefloor commented 3 years ago

No sorry, didn't have time to work on this yet. Maybe I'll work on it next week. Would be great if you can make a PR that I'll review.

fzyzcjy commented 3 years ago

@renefloor It does not matter. I am just afraid whether this issue is forgotten.

fzyzcjy commented 3 years ago

PR created: https://github.com/Baseflow/flutter_cache_manager/pull/319

fzyzcjy commented 3 years ago

@renefloor hi could you please have a look at the pr :)

renefloor commented 3 years ago

Thanks a lot for the work @fzyzcjy

fzyzcjy commented 3 years ago

@renefloor You are welcome!