Impeller 是专为 Flutter 打造的现代渲染引擎,由 Google 开发,旨在取代 Skia 并解决其根本性问题:首次渲染帧时的着色器延迟(jank)、高内存消耗以及支持不同图形后端的复杂性。与 Skia 不同,Impeller 预先(离线)编译着色器,使用 SPIR-V 作为中间表示,并直接与 Vulkan、Metal 和 Direct3D 12 协同工作。根据 Flutter Team (2025) 的数据,Impeller 消除了高达 95% 的着色器延迟,即使在入门级设备上也能提供可预测的 60 FPS。
要点
Impeller 是一个用 C++ 编写的开源图形渲染引擎,由 Flutter 团队开发,旨在取代 Skia 作为主要渲染器。该项目于 2021 年宣布,是对 Skia 长期存在的 shader jank 问题的回应。Impeller 不是 Skia 的分支——它是一个全新的实现,设计时充分考虑了移动 GPU 的限制和现代图形 API 的特点。
Impeller 的核心思想是将着色器编译从运行时转移到应用程序的构建阶段。在 Skia 中,着色器在首次使用时编译,此时用户已经与应用程序进行交互。Impeller 预先(离线)编译所有着色器,将它们打包为 SPIR-V 二进制格式,并与应用程序一起分发。在运行时,Impeller 加载预编译的着色器,从而消除了编译带来的延迟。
Impeller 还解决了内存消耗问题。Skia 在渲染过程中创建大量临时对象(纹理、缓冲区),导致资源受限设备上的内存碎片化。Impeller 使用内存池并重用已分配的资源,将峰值内存消耗降低 30–40%。
SPIR-V(Standard Portable Intermediate Representation)是 Khronos Group 开发的着色器中间表示。Impeller 使用 SPIR-V 作为所有着色器的通用格式。在构建阶段,使用 Impeller 语言(用于描述效果的专有 C++ DSL)编写的着色器被编译为 SPIR-V。在运行时,SPIR-V 被加载并转换为平台特定格式——Metal 的 MSL、Vulkan 的 GLSL 或 Direct3D 12 的 DXIL。
Impeller 的架构由多个层组成,每层执行严格定义的任务:处理渲染命令列表、管理 GPU 资源和执行着色器。这种模块化设计使得可以轻松添加对新图形 API 的支持。
底层——是对图形 API(Vulkan、Metal、Direct3D 12)的抽象。Impeller 不支持 OpenGL,因为 OpenGL 无法提供高效的离线着色器编译能力。在这一层实现了:顶点缓冲管理、管道(图形管线)的创建和缓存、GPU 同步。管道在 Impeller 中是预编译的 GPU 状态,包括着色器、光栅化和混合设置。所有管道在初始化阶段创建,从而消除了渲染期间的编译。
中间层——是资源管理系统。它分配和重用 GPU 资源:纹理、缓冲区、采样器。Impeller 不会在每帧创建新纹理,而是维护不同大小和格式的纹理池。内存池自动回收未使用的资源,并可以在需要时扩展,但不会出现 Skia 特有的碎片化问题。
上层——是 Flutter Engine 将 Canvas API 命令转换成的渲染图。Impeller 接收 Display List(绘图命令列表),并从中构建操作依赖图。该图经过优化:删除不必要的渲染通道,合并具有相同 GPU 状态的操作。然后,该图使用预先创建的管道编译为 Vulkan/Metal 调用序列。
每帧通过固定管线进行处理:Display List → 渲染图 → 图编译 → 发送 GPU 命令。可以为后处理效果(模糊、阴影)或深度缓冲区准备添加额外的通道。Impeller 中的帧时间比 Skia 更可预测,因为不存在着色器编译的非确定性延迟。
Impeller 和 Skia 的对比显示了两者在渲染方法上的差异。Skia 是一个通用的 2D 库,而 Impeller 是专为 Flutter 设计的专业化引擎,针对移动 UI 需求进行了优化。
| 参数 | Skia | Impeller |
|---|---|---|
| 着色器 | 运行时编译 | 离线编译(构建时) |
| Shader jank | 首帧 50–200 毫秒 | 无(0 毫秒) |
| 着色器格式 | 专有(SkSL) | SPIR-V(通用) |
| GPU 后端 | OpenGL、Vulkan、Metal | Vulkan、Metal、Direct3D 12 |
| 内存消耗 | 高(临时纹理) | 内存池,降低达 40% |
| 平台 | Android、iOS、Web、桌面 | Android、iOS、桌面 |
| 状态 | 稳定(主要) | 预览(取代 Skia) |
关键区别——对着色器的处理方式。Skia 在使用时编译着色器,在首次渲染不熟悉的效果时产生 shader jank。Impeller 通过离线编译消除了这一问题。Skia 还支持 OpenGL,这对于 Flutter 的 Web 版本是必要的,但 Impeller 放弃了 OpenGL,转而使用更现代的 API,从而在移动设备上提供更好的性能。
对于 Flutter 应用程序,迁移到 Impeller 不需要更改代码。Impeller 实现了与 Skia 相同的 Canvas API,因此所有小部件、动画和自定义绘图都能以相同方式工作。向后兼容性在 Flutter Engine 层面得到保证——引擎在应用程序初始化阶段选择渲染器(Skia 或 Impeller)。
Impeller 相比 Skia 提供了多个可衡量的优势,直接影响用户体验和 Flutter 应用程序的性能。
Shader jank 是 Skia 的主要问题,Impeller 彻底解决了它。当 Flutter 应用程序显示带有渐变、遮罩或非标准混合的新屏幕时,Skia 在动画期间编译着色器,导致帧丢失。Impeller 在构建阶段编译所有着色器,因此首帧与后续帧的渲染速度相同。在 GPU 速度较慢的设备上(MediaTek Helio、Qualcomm 400 series),差异尤为明显——Skia 中每种新效果类型最多延迟 200 毫秒,而 Impeller 中为 0 毫秒。
Impeller 使用资源池来管理 GPU 内存。在 Skia 中,每帧都可能为临时表面创建新纹理,尤其是在使用透明度渲染或使用 saveLayer 时。Impeller 在帧之间重用纹理,将 Android 上的峰值内存消耗降低 30–40%,iOS 上降低 25%。这对于具有长列表和动画的应用程序尤其重要,Skia 在 2 GB RAM 的设备上可能导致 OOM 错误。
在 Skia 中,帧渲染时间可能因已编译的着色器而异。带有新效果的首帧可能需要 50–200 毫秒,而后续帧为 3–5 毫秒。这种不可预测性使优化和测试变得困难。Impeller 确保帧时间一致,因为所有着色器都已编译,内存分配是可预测的。使用 Impeller 的 Flutter Engine 可以更精确地计算每帧的时间预算。
Impeller 直接与 Vulkan(Android)、Metal(iOS)和 Direct3D 12(Windows)协同工作,无需 OpenGL 层。这提供了几个优势:更低的驱动延迟(比通过 OpenGL 减少高达 50%)、对 GPU 内存的直接控制以及访问现代功能(基于图块的 GPU 架构、GPU-driven rendering)。OpenGL 已不再发展,其在移动设备上的驱动常常成为性能瓶颈。
Impeller 处于积极开发阶段,可在 Flutter Master 和 Beta 频道中使用。从 Flutter 3.16 开始,Impeller 在 iOS 上默认启用,在 Android 上则通过配置标志可选。Skia 被 Impeller 完全取代预计在 2026 年的某个稳定版 Flutter 中实现。
在 iOS 上,Impeller 通过 Metal 运行,自 Flutter 3.16 起默认启用。Flutter 团队建议在 Impeller 上测试应用程序并报告问题。要回退到 Skia,请在 Info.plist 文件中使用 Impeller 标志:FlutterEnableImpeller = NO。根据 Flutter Team 的数据,92% 的 iOS 应用程序在 Impeller 上运行没有可见的回归,动画性能提升 25–40%。
在 Android 上,Impeller 通过 Vulkan 运行。要启用它,请在 AndroidManifest.xml 中添加 meta-tag:io.flutter.embedded_views_preview。Flutter 团队正在继续针对不同的 GPU 架构(Adreno、Mali、PowerVR)优化 Impeller。Android 上的主要挑战是支持没有 Vulkan 的设备(Android < 7.0 或旧 GPU)。对于此类设备,将使用 Skia 的回退后端或具有软件光栅化的 Impeller。
在 Windows 上,Impeller 通过 Direct3D 12 运行(在 Flutter Master 中已启用)。在 macOS 和 Linux 上——分别通过 Metal 和 Vulkan。Web 版不计划使用 Impeller,因为 Flutter 的 Web 版本使用 CanvasKit(通过 WebAssembly 使用 Skia),并且由于浏览器中不同的着色器编译机制,shader jank 不是关键问题。Web 版本将继续使用 Skia。
Google 发布了 Impeller 的路线图:2024 年——Impeller 在 iOS 上默认;2025 年——Impeller 在 Android 和 Windows 上默认;2026 年——从 Flutter Engine 中完全移除 Skia。此后,Flutter 将使用 Impeller 作为唯一的渲染引擎,这将简化支持、减小引擎大小并提高所有平台上的性能。
常见问题
在 iOS 上,Impeller 自 Flutter 3.16 起默认启用。在 Android 上,请在 AndroidManifest.xml 中添加值为 true 的 meta-tag io.flutter.embedded_views_preview。在 Windows 上,启动时使用 --enable-impeller 标志。在所有情况下,都可以通过 Dart 代码中的 FlutterEngine 强制启用。
Skia 能用,但存在根本性问题:shader jank(着色器编译延迟 50–200 毫秒)、高内存消耗和 OpenGL 架构的限制。Impeller 专为 Flutter 设计,通过离线着色器编译和内存池解决了这些问题。
是的,Impeller 实现了与 Skia 相同的 Canvas API。所有标准的 Flutter 小部件——文本、图像、动画、自定义 paint——无需更改即可在 Impeller 上运行。向后兼容性在 Flutter Engine 层面得到保证,迁移对开发者是透明的。
不可以,应用程序每次只能使用一个渲染引擎。选择是在 Flutter Engine 初始化时通过标志进行的。在应用程序运行期间无法在 Skia 和 Impeller 之间切换——渲染器在创建第一个 FlutterEngine 实例之前就已确定。
Skia 将继续作为 Google 的独立库存在,用于 Chrome、Android 和其他项目。在 Flutter 中,Skia 将被 Impeller 取代成为主要渲染器。Skia 将保留用于 Flutter 的 Web 版本(通过 CanvasKit)以及作为不支持 Vulkan/Metal 设备的后备选项。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。