Flutter图片加载优化,自动缓存大小

Flutter图片加载优化:解决大图内存问题

在移动应用开发中,图片加载是一个常见但容易出问题的环节。我们在开发安卓APP时,使用Glide加载图片,它会默认按照view的尺寸进行图片缓存。但是在Flutter中,默认缓存使用的是图片原始大小。这会导致图片加载过程中占用内存比较大。如果你在iOS设备上加载一个图片列表,每张图片在2M左右时,应用可能会崩溃。

问题现象

在Flutter开发过程中,我们经常使用各种类型的图片加载。当你加载一张尺寸比较大(9248x6944)的图片时,会发现图片加载很慢,即使它是本地图片。

dart 复制代码
Image.asset(
  Assets.imgBig,
  width: 200,
  height: 200,
),

这时打开debugInvertOversizedImages = true;这个配置,可以看到图片会颜色反转同时倒置,同时日志会提示图片过载。

dart 复制代码
======== Exception caught by painting library ======================================================
The following message was thrown while painting an image:
Image assets/img/big.jpg has a display size of 525×525 but a decode size of 6151×8192, which uses an additional 261007KB.

Consider resizing the asset ahead of time, supplying a cacheWidth parameter of 525, a cacheHeight parameter of 525, or using a ResizeImage.
====================================================================================================

解决方案

使用ResizeImage

根据提示,我们可以使用cacheWidth, cacheHeightResizeImage。查看源码发现,当设置了cacheWidthcacheHeight时,本质是使用ResizeImage包裹ImageProvider

dart 复制代码
Image.asset(
  String name, {
}) : image = ResizeImage.resizeIfNeeded(
       cacheWidth,
       cacheHeight,
       scale != null
         ? ExactAssetImage(name, bundle: bundle, scale: scale, package: package)
         : AssetImage(name, bundle: bundle, package: package),
     ),

自定义AutoResizeImage

我们自定义一个AutoResizeImage来代替系统的ResizeImage,支持在图片不过载的前提下,满足图片的清晰度,同时支持清晰度调节。主要逻辑就是根据控件尺寸,调整图片解码尺寸。

dart 复制代码
@override
ImageStreamCompleter loadBuffer(AutoResizeImageKey key, DecoderBufferCallback decode) {
  Future<Codec> decodeResize(ImmutableBuffer buffer, {int? cacheWidth, int? cacheHeight, bool? allowUpscaling}) async {
    final ImageDescriptor descriptor = await ImageDescriptor.encoded(buffer);
    Size resize = _resize(descriptor);
    return descriptor.instantiateCodec(
      targetWidth: resize.width.round(),
      targetHeight: resize.height.round(),
    );
  }

  final ImageStreamCompleter completer = imageProvider.loadBuffer(key._providerCacheKey, decodeResize);
  if (!kReleaseMode) {
    completer.debugLabel = '${completer.debugLabel} - Resized(${key._width}×${key._height})';
  }
  _configureErrorListener(completer, key);
  return completer;
}

iOS开发辅助工具

在进行Flutter开发时,特别是针对iOS平台的优化,使用专业的工具可以事半功倍。AppUploader作为一款专业的iOS开发助手,可以帮助开发者更高效地管理应用打包、上传和测试流程。它支持批量处理图片资源,自动优化图片大小,与本文提到的图片加载优化方案完美配合,能显著提升应用性能并减少内存占用。

使用建议

  1. 对于网络图片,建议使用CachedNetworkImage配合AutoResizeImage
  2. 对于本地资源图片,可以直接使用AutoResizeImage包裹AssetImage
  3. 在列表等需要加载多张图片的场景,务必使用尺寸优化方案
  4. 开发阶段保持debugInvertOversizedImages = true以便及时发现图片过载问题

通过合理的图片加载策略和专业的开发工具配合,可以显著提升Flutter应用在iOS设备上的性能和稳定性。

相关推荐
.生产的驴8 分钟前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
景天科技苑16 分钟前
【Rust】Rust中的枚举与模式匹配,原理解析与应用实战
开发语言·后端·rust·match·enum·枚举与模式匹配·rust枚举与模式匹配
追逐时光者1 小时前
MongoDB从入门到实战之Docker快速安装MongoDB
后端·mongodb
方圆想当图灵1 小时前
深入理解 AOP:使用 AspectJ 实现对 Maven 依赖中 Jar 包类的织入
后端·maven
豌豆花下猫1 小时前
Python 潮流周刊#99:如何在生产环境中运行 Python?(摘要)
后端·python·ai
嘻嘻嘻嘻嘻嘻ys1 小时前
《Spring Boot 3 + Java 17:响应式云原生架构深度实践与范式革新》
前端·后端
异常君1 小时前
线程池隐患解析:为何阿里巴巴拒绝 Executors
java·后端·代码规范
mazhimazhi1 小时前
GC垃圾收集时,居然还有用户线程在奔跑
后端·面试
Python私教1 小时前
基于 Requests 与 Ollama 的本地大模型交互全栈实践指南
后端
ypf52081 小时前
Tortoise_orm与Aerich 迁移
后端