Impeller:关键概念、架构与优势

作者: IT Sectr 发布日期: 2026-06-04 阅读时间: 9 分钟

Impeller 是专为 Flutter 打造的现代渲染引擎,由 Google 开发,旨在取代 Skia 并解决其根本性问题:首次渲染帧时的着色器延迟(jank)、高内存消耗以及支持不同图形后端的复杂性。与 Skia 不同,Impeller 预先(离线)编译着色器,使用 SPIR-V 作为中间表示,并直接与 Vulkan、Metal 和 Direct3D 12 协同工作。根据 Flutter Team (2025) 的数据,Impeller 消除了高达 95% 的着色器延迟,即使在入门级设备上也能提供可预测的 60 FPS。

要点

  • Impeller — 替代 Skia 的全新 Flutter 渲染引擎
  • 离线编译着色器消除了首次渲染时的 shader jank
  • 架构使用 SPIR-V 作为通用中间表示
  • 后端Impeller 直接与 Vulkan、Metal 和 Direct3D 12 协同工作
  • 性能得益于所有着色器的预处理而变得可预测

什么是 Impeller?

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 作为基础

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 如何工作?

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 调用序列。

Impeller 中的帧执行流程

每帧通过固定管线进行处理:Display List → 渲染图 → 图编译 → 发送 GPU 命令。可以为后处理效果(模糊、阴影)或深度缓冲区准备添加额外的通道。Impeller 中的帧时间比 Skia 更可预测,因为不存在着色器编译的非确定性延迟。

Impeller vs Skia:对比

Impeller 和 Skia 的对比显示了两者在渲染方法上的差异。Skia 是一个通用的 2D 库,而 Impeller 是专为 Flutter 设计的专业化引擎,针对移动 UI 需求进行了优化。

参数SkiaImpeller
着色器运行时编译离线编译(构建时)
Shader jank首帧 50–200 毫秒无(0 毫秒)
着色器格式专有(SkSL)SPIR-V(通用)
GPU 后端OpenGL、Vulkan、MetalVulkan、Metal、Direct3D 12
内存消耗高(临时纹理)内存池,降低达 40%
平台Android、iOS、Web、桌面Android、iOS、桌面
状态稳定(主要)预览(取代 Skia)

关键区别——对着色器的处理方式。Skia 在使用时编译着色器,在首次渲染不熟悉的效果时产生 shader jank。Impeller 通过离线编译消除了这一问题。Skia 还支持 OpenGL,这对于 Flutter 的 Web 版本是必要的,但 Impeller 放弃了 OpenGL,转而使用更现代的 API,从而在移动设备上提供更好的性能。

与现有 Flutter 代码的兼容性

对于 Flutter 应用程序,迁移到 Impeller 不需要更改代码。Impeller 实现了与 Skia 相同的 Canvas API,因此所有小部件、动画和自定义绘图都能以相同方式工作。向后兼容性在 Flutter Engine 层面得到保证——引擎在应用程序初始化阶段选择渲染器(Skia 或 Impeller)。

Impeller 的优势

Impeller 相比 Skia 提供了多个可衡量的优势,直接影响用户体验和 Flutter 应用程序的性能。

消除 shader jank

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 可以更精确地计算每帧的时间预算。

支持现代图形 API

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 默认

在 iOS 上,Impeller 通过 Metal 运行,自 Flutter 3.16 起默认启用。Flutter 团队建议在 Impeller 上测试应用程序并报告问题。要回退到 Skia,请在 Info.plist 文件中使用 Impeller 标志:FlutterEnableImpeller = NO。根据 Flutter Team 的数据,92% 的 iOS 应用程序在 Impeller 上运行没有可见的回归,动画性能提升 25–40%。

Android:可选

在 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。

桌面和 Web

在 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 作为唯一的渲染引擎,这将简化支持、减小引擎大小并提高所有平台上的性能。

常见问题

如何在 Flutter 中启用 Impeller?

在 iOS 上,Impeller 自 Flutter 3.16 起默认启用。在 Android 上,请在 AndroidManifest.xml 中添加值为 true 的 meta-tag io.flutter.embedded_views_preview。在 Windows 上,启动时使用 --enable-impeller 标志。在所有情况下,都可以通过 Dart 代码中的 FlutterEngine 强制启用。

既然 Skia 能用,为什么还要替换它?

Skia 能用,但存在根本性问题:shader jank(着色器编译延迟 50–200 毫秒)、高内存消耗和 OpenGL 架构的限制。Impeller 专为 Flutter 设计,通过离线着色器编译和内存池解决了这些问题。

Impeller 是否支持所有 Flutter 小部件?

是的,Impeller 实现了与 Skia 相同的 Canvas API。所有标准的 Flutter 小部件——文本、图像、动画、自定义 paint——无需更改即可在 Impeller 上运行。向后兼容性在 Flutter Engine 层面得到保证,迁移对开发者是透明的。

可以同时使用 Skia 和 Impeller 吗?

不可以,应用程序每次只能使用一个渲染引擎。选择是在 Flutter Engine 初始化时通过标志进行的。在应用程序运行期间无法在 Skia 和 Impeller 之间切换——渲染器在创建第一个 FlutterEngine 实例之前就已确定。

Impeller 实施后 Skia 会怎样?

Skia 将继续作为 Google 的独立库存在,用于 Chrome、Android 和其他项目。在 Flutter 中,Skia 将被 Impeller 取代成为主要渲染器。Skia 将保留用于 Flutter 的 Web 版本(通过 CanvasKit)以及作为不支持 Vulkan/Metal 设备的后备选项。

总结

  • Impeller — 全新 Flutter 渲染引擎,通过离线着色器编译消除 shader jank
  • 架构基于 SPIR-V、预编译管道和内存池
  • 对比Skia:首次渲染无延迟,内存减少 30–40%
  • 后端支持 Vulkan、Metal 和 Direct3D 12,无需过时的 OpenGL
  • 状态iOS 上默认启用,Android 和 Windows 上可选(Flutter 3.16+)
  • 兼容性完全兼容:所有现有 Flutter 小部件无需更改代码即可运行
  • 建议在全新的 Flutter 项目中使用 Impeller,并迁移现有项目以消除延迟

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读