Improving Shader Jank Performance in Flutter with Impeller

Hello everyone,
Stuttering during scrolling, unresponsive animations, or delays on the first click... these are classic performance problems you might face as a mobile developer.
Technically, these types of delays are called jank.
In this article, we'll discuss how Flutter's new graphics engine, Impeller, solves this problem and what it offers to developers with the latest information.
🎯 Why Does Jank Problem Occur?
Flutter is a framework that effectively utilizes the GPU to produce high-performance interfaces. However, in some cases, the user interface can stutter, causing the app to run smoothly. These issues are particularly evident during animations , visual effects like blur/gradient , or scrolling lists .
So why? This is primarily because small graphics programs called shaders are compiled "on the fly" to the GPU while the app is running. This instant compilation occupies the UI thread and causes lag. The solution to this problem comes with Impeller , Flutter's new graphics engine .
đź§ You can actually compare this situation to compiling a Flutter project for the first time.
The first run involves
pub get, Gradle synchronization, and cache file creation, which takes a long time. But once these operations are complete, you get an.apkor.appoutput, and subsequent runs are much faster.
Similarly, when Flutter first shows a new visual effect, it tries to compile the shader to the GPU at that moment. This blocks the UI thread and causes jank. Impeller, on the other hand, pre-compiles these shaders and provides them ready to the application—just like a project you’ve built once, which opens at lightning speed on subsequent runs.
What is a Shader?
Shaders are small programs that run on the GPU. Many effects you see on the screen, like gradients, blurs, or shadows, are powered by shaders.
Flutter primarily uses Impeller now by default, whereas earlier versions relied on Skia . This engine compiles and sends shaders to the GPU at runtime. However, even a few milliseconds of this process can cause noticeable UI stutter. This is why this issue , especially during initial launches, is called shader lag .
For example, a user opens the app and there's a scrollable list on the homepage. You use a slight blur effect behind each item in this list. If the shader for this effect has never been compiled before, the list will hang momentarily as the user scrolls. This is because Flutter is having the GPU compile the shader, and the UI thread will block briefly during that time.
This is where Impeller comes into play.
What is Impeller?
Impeller is a new rendering engine developed by the Flutter team . It aims to replace the long-used Skia . Starting with Flutter 3.27, it's enabled by default on iOS and Android API 29+.
What Does Impeller Do?
Impeller's main goals are:
- âś… Pre-compile shaders
- âś… Provide consistent performance regardless of the platform
- âś… Prevent jank from occurring ahead of time
Impeller compiles shaders while the application is being built and makes them available to the GPU at runtime on the device. This means no shader compilation takes place when the user runs the app—thus eliminating problems like "stuttering in the first animation" or "lagging while scrolling a list."
📦 Bonus: _Goodbye SkSL Warm-Up!_
One way to reduce jank with Skia was to perform an "SkSL warm-up" when the app first opened. Shaders were recorded and embedded into the next build. However, this method was cumbersome and had to be redone for each device.
With Impeller, this process is a thing of the past. Seamless shader management is provided on all devices with a single build.
Skia vs. Impeller
đź”· When Using Skia:
- Shaders are compiled at runtime.
- Glazing may occur during first use.
- SkSL caching may be required for each device.
- Performance varies by device and usage situation.
- There is platform dependency.
🟢 When Using Impeller:
- Shaders are compiled at build time.
- Jank risk is largely eliminated.
- The need for SkSL warm-up is eliminated.
- Provides more stable, predictable performance.
- It is platform independent.
🛠️How to Activate Impeller?
Incorporating Impeller into your project is quite easy. Follow the steps below to start working with Impeller in your application.
For iOS
Starting Flutter 3.29, Impeller is the default rendering engine on iOS, and there's no option to opt out.
iOS (Before Flutter 3.29)
Enable Impeller Manually
Debug Builds (via CLI)
flutter run --enable-impeller
Release Builds (via Info.plist)
<key>FLTEnableImpeller</key>
<true/>
Disable Impeller (if needed)
Debug Builds (via CLI)
flutter run --no-enable-impeller
Release Builds (via Info.plist)
<key>FLTEnableImpeller</key>
<true/>
For Android
From 3.27, Impeller is the default rendering engine on modern Android devices (Android API 29+) and automatically falls back to the legacy Skia (OpenGL) renderer on older or Vulkan-unsupported devices.
Android (Before and After Flutter 3.27)
Enable Impeller Manually
Debug Builds (via CLI)
flutter run --enable-impeller
Release Builds (AndroidManifest.xml)
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="true"
/>
Disable Impeller (if needed)
Debug Builds (via CLI)
flutter run --no-enable-impeller
Release Builds (AndroidManifest.xml)
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="false"
/>
If you want flutter/devtools, you can also check whether it is active in runtime.
How Do I Know If My Impeller Is Working?
-
Observe: Check the fluidity of shader-based sections of the application, such as scrolling, animation, or blur. If there's no stuttering even on initial interaction, it's the Impeller's work.
-
Performance Monitor (DevTools): You can check if you're seeing any shader compilation overhead by going to the Performance tab in DevTools . If impeller is enabled, shader compile time won't be visible.
-
Log Output:
flutter runAfter the command, the following message appears in the log:Impeller: Enabled
Why is Impeller Important to the Flutter Ecosystem?
Impeller is the foundation for Flutter to be more predictable , consistent , and performant across multiple platforms . It significantly improves the developer experience by eliminating issues like shader warm-up and device dependency.
In short, if you want smoother animations, no stutter on first interactions, and stable performance across devices—Impeller is your solution.
Well, friends, in this article, I tried to explain as much as I could why the shader jank problem in Flutter occurs and how to solve this problem with Impeller .
Thank you for reading!
