关于 coil-compose
面向 Compose 和 Compose Multiplatform 的 Coil 3 参考技能。内容说明跨平台上下文选择与图片加载性能限制,包括何时避免子组合以及如何为 Painter 请求指定尺寸。
主要功能
- 01跨平台使用 LocalPlatformContext
- 02设置共享 ImageLoader
- 03区分 coil-compose 与 core
- 04列表中避免 SubcomposeAsyncImage
- 05为 Painter 请求指定尺寸
适用场景
- 01在 commonMain 中加载图片
- 02配置跨平台图片加载器
- 03减少 LazyColumn 图片滚动卡顿
- 04避免 Painter 加载超大原图
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rcosteira79/ android-skills --skill coil-compose安装后在 Claude Code 中输入/coil-compose确认已加载。
详细介绍
Coil 3 for Compose & Compose Multiplatform
本参考介绍 KMP 的特定内容和两项性能防护措施,不涉及 AsyncImage / SubcomposeAsyncImage / ImageRequest / placeholder / error / contentDescription / 共享 ImageLoader 的基础知识。
KMP:使用 LocalPlatformContext,而不是 LocalContext
Coil 3 完全支持多平台——AsyncImage / SubcomposeAsyncImage / rememberAsyncImagePainter 在 commonMain 中完全相同,无需 expect/actual。唯一需要替换的是:使用 LocalPlatformContext.current,而不是 LocalContext.current(仅适用于 Android;在 commonMain 中会导致编译错误)。它在 Android 上会解析为 android.content.Context,在其他目标平台上则解析为 PlatformContext.INSTANCE。
// commonMain — works on all platforms
AsyncImage(
model = ImageRequest.Builder(LocalPlatformContext.current).data(url).crossfade(true).build(),
contentDescription = "User avatar",
modifier = Modifier.size(48.dp).clip(CircleShape),
)
**单例设置(KMP):在应用生命周期早期调用一次 SingletonImageLoader.setSafe { ImageLoader.Builder(it).crossfade(true).build() },或显式传入 imageLoader。coil-compose 与 coil-compose-core:**使用 coil-compose 时,不带 imageLoader 参数的 AsyncImage 会自动使用单例;使用 coil-compose-core 时,必须提供 imageLoader 参数(没有单例便捷用法)。按需添加平台网络引擎(例如,用于 KMP 的 coil-network-ktor3)。
两项性能防护措施
**SubcomposeAsyncImage 比常规组合慢得多——切勿在 LazyColumn / LazyRow 中使用。**它会为每个条目创建一个子组合;滚动时,这项开销会不断累积,造成明显卡顿。若要在列表中自定义加载/错误状态,请改用带 placeholder / error 参数的 AsyncImage——视觉效果相同,且不会产生子组合。
rememberAsyncImagePainter 不会根据布局约束推断显示尺寸——如果没有显式设置 .size(),它会按原始尺寸加载图像(即使一张 4000×3000 的照片只显示为 64dp,内存中仍会占用整张位图 → 在包含 50 个条目的列表中可能导致 OOM)。只有在确实需要 Painter 时(Canvas、Icon、自定义绘制)才使用它;并且务必传入 .size()。其他情况请使用会自动调整尺寸的 AsyncImage。
// only when a Painter is genuinely required — explicit size is mandatory
val painter = rememberAsyncImagePainter(
ImageRequest.Builder(LocalPlatformContext.current).data(url).size(Size(128, 128)).build(),
)
Image(painter = painter, contentDescription = null)