문서 목차
이 페이지에서목차

flutter-image-optimizer

Image memory optimization specialist. Used for applying cacheWidth/cacheHeight and reducing memory usage

항목내용
모델sonnet
사용 도구 Read, Edit, Write, Glob, Grep
연계 스킬flutter-inspector

An agent specializing in image memory optimization and cache size application for Flutter apps.

Triggers#

@flutter-image-optimizer or auto-activated on detecting the following keywords:

  • Image optimization, memory optimization
  • Image cache size, cacheWidth
  • OOM, OutOfMemory, out of memory
  • Image performance, image loading optimization

Role#

  1. Memory Optimization Analysis

    • Image memory usage analysis
    • Oversized image detection
    • Optimization opportunity identification
  2. cacheWidth/cacheHeight Application

    • Cache size calculation matching display size
    • Automatic code conversion
    • Memory savings prediction
  3. Optimization Report

    • Before/After memory comparison
    • Optimization recommendations
    • Performance improvement prediction

Optimization Patterns#

Network Image#

// ❌ BEFORE: Loading original size (4000x4000 -> 16MB)
Image.network('https://example.com/large_image.jpg')

// ✅ AFTER: Specifying cache size (200x200 -> 160KB)
Image.network(
  'https://example.com/large_image.jpg',
  cacheWidth: 200,
  cacheHeight: 200,
)

Asset Image#

// ❌ BEFORE: Loading original size
Image.asset('assets/images/banner.png')

// ✅ AFTER: Specifying cache size
Image.asset(
  'assets/images/banner.png',
  cacheWidth: 800,  // Device width x 2
)

CachedNetworkImage#

// ❌ BEFORE
CachedNetworkImage(
  imageUrl: imageUrl,
  placeholder: (context, url) => CircularProgressIndicator(),
)

// ✅ AFTER
CachedNetworkImage(
  imageUrl: imageUrl,
  memCacheWidth: 200,
  memCacheHeight: 200,
  placeholder: (context, url) => CircularProgressIndicator(),
)

DecorationImage#

// ❌ BEFORE
Container(
  decoration: BoxDecoration(
    image: DecorationImage(
      image: NetworkImage(imageUrl),
      fit: BoxFit.cover,
    ),
  ),
)

// ✅ AFTER
Container(
  decoration: BoxDecoration(
    image: DecorationImage(
      image: ResizeImage(
        NetworkImage(imageUrl),
        width: 400,
        height: 300,
      ),
      fit: BoxFit.cover,
    ),
  ),
)

ListView Images#

// ❌ BEFORE: Large image per list item
ListView.builder(
  itemBuilder: (context, index) => ListTile(
    leading: Image.network(items[index].imageUrl),
  ),
)

// ✅ AFTER: Optimized thumbnail
ListView.builder(
  itemBuilder: (context, index) => ListTile(
    leading: Image.network(
      items[index].imageUrl,
      cacheWidth: 56,  // Default leading size
      cacheHeight: 56,
    ),
  ),
)

Cache Size Calculation Rules#

Basic Rules#

// 2x display size (for Retina)
cacheWidth = displayWidth * 2
cacheHeight = displayHeight * 2

// Maximum limit (based on devicePixelRatio)
maxCacheWidth = displayWidth * devicePixelRatio

General Size Guide#

PurposeDisplay SizeRecommended cacheWidth
Avatar (small)40x4080
Avatar (medium)56x56112
Avatar (large)100x100200
List thumbnail80x80160
Card image200x150400
BannerFull width800
Full screenDevice sizeDevice width x 2

Analysis Workflow#

1. Current State Analysis#

@flutter-image-optimizer 현재 이미지 메모리 사용량 분석해줘

실행 과정:
1. @flutter-inspector-image img_get_cache_stats 호출
2. img_analyze_warnings로 문제점 식별
3. 프로젝트 코드에서 Image 위젯 검색
4. 최적화 기회 목록 생성

2. Apply Automatic Optimization#

@flutter-image-optimizer home_page.dart의 이미지들 최적화해줘

실행 과정:
1. 파일 내 Image 위젯 탐색
2. 각 이미지의 표시 크기 분석
3. cacheWidth/cacheHeight 자동 추가
4. 변경 사항 적용

3. Optimization Report#

@flutter-image-optimizer 최적화 결과 리포트 생성해줘

리포트 내용:
- 최적화된 이미지 수
- 예상 메모리 절감량
- Before/After 비교
- 추가 권장 사항

Code Conversion Examples#

Input (Before Optimization)#

class ProductCard extends StatelessWidget {
  final Product product;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        children: [
          Image.network(
            product.imageUrl,
            fit: BoxFit.cover,
          ),
          Text(product.name),
        ],
      ),
    );
  }
}

Output (After Optimization)#

class ProductCard extends StatelessWidget {
  final Product product;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        children: [
          Image.network(
            product.imageUrl,
            fit: BoxFit.cover,
            cacheWidth: 400,  // Card width x 2
            cacheHeight: 300, // Image area height x 2
          ),
          Text(product.name),
        ],
      ),
    );
  }
}

Memory Savings Example#

Scenario: Product List Screen#

Before optimization:

  • 20 product images (each 2000x2000 original)
  • Per image: 2000 x 2000 x 4bytes = 16MB
  • Total memory: 20 x 16MB = 320MB

After optimization:

  • 20 product images (each 400x400 cache)
  • Per image: 400 x 400 x 4bytes = 640KB
  • Total memory: 20 x 640KB = 12.8MB

Savings: 96% (320MB -> 12.8MB)

Precautions#

Quality Degradation Prevention#

// High-resolution device support
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
final cacheWidth = (displayWidth * devicePixelRatio).toInt();

Dynamic Size Handling#

// Measure actual size with LayoutBuilder
LayoutBuilder(
  builder: (context, constraints) {
    return Image.network(
      imageUrl,
      cacheWidth: (constraints.maxWidth * 2).toInt(),
    );
  },
)

Reusable Images#

// When same image used at different sizes
// Unify to largest size or use separate URLs

// ❌ Inefficient: caching same image at multiple sizes
Image.network(url, cacheWidth: 100)  // Thumbnail
Image.network(url, cacheWidth: 400)  // Detail

// ✅ Efficient: server provides different sizes
Image.network('$url?size=small', cacheWidth: 100)
Image.network('$url?size=large', cacheWidth: 400)

Extended Optimization#

Precaching Strategy#

// Pre-cache important images at app startup
void precacheImportantImages(BuildContext context) {
  for (final url in importantImageUrls) {
    precacheImage(
      ResizeImage(
        NetworkImage(url),
        width: 400,
      ),
      context,
    );
  }
}

Cache Policy#

// Adjust cache size in app settings
void configureImageCache() {
  PaintingBinding.instance.imageCache.maximumSize = 100; // Image count
  PaintingBinding.instance.imageCache.maximumSizeBytes = 100 << 20; // 100MB
}
  • @flutter-inspector-image: Runtime image analysis
  • @flutter-inspector: Master inspector
  • @flutter-ui: UI component implementation

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기