How PowerImage Revolutionizes Flutter Image Handling with FFI and Texture
PowerImage, Alibaba’s next‑generation Flutter image library, combines native‑level FFI and texture techniques to deliver ui.Image support, pre‑loading, unified caching, simulator compatibility, custom image channels, and performance‑optimized rendering, while providing extensive unit tests and open‑source tooling for developers.
Background
Last year the Xianyu tech team released the next‑generation image library PowerImage, which after extensive gray‑testing, bug fixing and code optimization is now fully stable in production.
Introduction
PowerImage is a highly extensible Flutter image library that fully leverages native image‑library capabilities. By combining external texture with an FFI solution it stays close to native design and solves several business pain points.
Key Features
Supports loading ui.Image directly, enabling use cases where external texture alone cannot provide an image.
Provides image pre‑loading similar to native precacheImage.
Introduces texture cache that integrates with native image cache, unifying memory management.
Works on simulators (flutter ≤ 1.23.0‑18.1.pre) where texture widgets previously failed.
Custom image‑type channel for scenarios such as album images.
Comprehensive exception capture.
Supports animated images (contributed by Taote).
Flutter Native Image Pipeline
The native Image widget obtains an ImageStream from an ImageProvider, listens to its state and finally builds a RawImage using ImageInfo that contains a ui.Image. Image – displays loading, error and success states. ImageProvider – creates the ImageStream (e.g., NetworkImage, AssetImage). ImageStream – the object that loads the image data.
New Generation Solution
We combine an FFI approach with external texture. The native side passes memory address and length to Flutter, which creates a ui.Image. Because decodeImageFromPixels copies memory, we explore two optimizations: let Flutter decode the data, or work with the Flutter team to reduce the copy.
Problem 1 – Image Widget Needs ui.Image
We expose an imageBuilder to let callers supply a custom widget.
Problem 2 – ImageCache Size Calculation
We customize the texture side to provide a fake ui.Image for cache size, or read size from ImageInfo directly.
Problem 3 – Native‑side Texture Lifecycle
We modify ImageCache release logic (partial code shown) to handle native‑side release timing.
Overall Architecture
PowerImageProvider creates appropriate ImageInfo for either FFI or texture. PowerImageLoader supplies unified loading and releasing. Custom ImageExt widget exposes imageBuilder for texture, and ImageCacheExt extends cache handling for Flutter <2.2.0.
Data
Benchmark on iPhone 11 Pro (300 network images, ListView scroll) shows memory fluctuation of 186 MB for FFI and 194 MB for texture; UI thread time is best with texture, while raster thread time favors PowerImage.
FFI vs Texture
Both approaches have similar memory peaks on Flutter 2.5.3, but FFI benefits from raster cache for smoother scrolling.
Scrolling Smoothness Analysis
On Android OnePlus 8T with locked CPU/GPU, UI thread cost is lowest with texture, PowerImage outperforms IFImage on raster thread, and native resize gives the best performance.
More Concise Code
FFI reduces Dart code size because it shares more logic with native image handling.
Unit Tests
PowerImage maintains ~95 % line coverage with extensive unit tests.
Open Source
The project is hosted on GitHub and published on pub.dev. Contributors are encouraged to file issues with detailed information and submit PRs that pass the automated flutter test workflow.
Future
PowerImage will continue evolving, favoring the FFI path as Flutter advances, while keeping texture support for compatibility.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
