Impeller е модерен механизъм за рендиране (rendering engine) за Flutter, разработен от Google за замяна на Skia и отстраняване на нейните фундаментални проблеми: забавяния на шейдъри (jank) при първото рендиране на кадри, висока консумация на памет и трудност при поддръжката на различни графични backend. За разлика от Skia, Impeller компилира шейдърите предварително (offline), използва SPIR-V като междинно представяне и работи директно с Vulkan, Metal и Direct3D 12. Според данни на Flutter Team (2025), Impeller премахва до 95% от забавянията на шейдъри, осигурявайки предвидими 60 FPS дори на начални устройства.
Основни точки
Impeller — е графичен механизъм за рендиране с отворен код, написан на C++, който се разработва от екипа на Flutter за замяна на Skia като основен renderer. Проектът беше обявен през 2021 г. като отговор на дългогодишния проблем shader jank, от който страда Skia. Impeller не е форк на Skia — това е напълно нова имплементация, проектирана с оглед на ограниченията на мобилните GPU и съвременните графични API.
Основната идея на Impeller е преместването на компилацията на шейдъри във фазата на изграждане (build) на приложението, а не по време на изпълнение. В Skia шейдърите се компилират при първата употреба, когато потребителят вече взаимодейства с приложението. Impeller компилира всички шейдъри предварително (offline), опакова ги в двоичен формат SPIR-V и ги доставя заедно с приложението. По време на изпълнение Impeller зарежда предварително компилираните шейдъри, което елиминира забавянията, свързани с компилация.
Impeller също така решава проблема с консумацията на памет. Skia създава множество временни обекти (текстури, буфери) в процеса на рендиране, което води до фрагментация на паметта на устройства с ограничени ресурси. Impeller използва паметови пулове (memory pools) и повторно използва вече разпределените ресурси, намалявайки пиковата консумация на памет с 30–40%.
SPIR-V (Standard Portable Intermediate Representation) — е междинно представяне на шейдъри, разработено от Khronos Group. Impeller използва SPIR-V като универсален формат за всички шейдъри. Във фазата на изграждане шейдърите на езика Impeller (собствен C++ DSL за описание на ефекти) се компилират до SPIR-V. По време на изпълнение SPIR-V се зарежда и превежда във формат, специфичен за платформата — MSL за Metal, GLSL за Vulkan или DXIL за Direct3D 12.
Архитектурата на Impeller се състои от няколко слоя, всеки от които изпълнява строго определена задача: обработка на списъка с команди за рендиране, управление на GPU ресурси и изпълнение на шейдъри. Тази модулност позволява лесно добавяне на поддръжка за нови графични API.
Долният слой — е абстракция над графичния API (Vulkan, Metal, Direct3D 12). Impeller не поддържа OpenGL, тъй като OpenGL не предоставя възможности за ефективна offline компилация на шейдъри. На това ниво са имплементирани: управление на буфери за върхове, създаване и кеширане на pipeline-ове (графични конвейери), синхронизация на GPU. Pipeline в Impeller — е предварително компилирано състояние на GPU, което включва шейдъри, настройки за растеризация и blending. Всички pipeline-ове се създават във фазата на инициализация, което елиминира компилация по време на рендиране.
Средният слой — е системата за управление на ресурси. Тя разпределя и повторно използва GPU ресурси: текстури, буфери, семплери. Вместо да създава нова текстура при всеки кадър, Impeller поддържа пул от текстури с различни размери и формати. Паметовият пул автоматично връща неизползваните ресурси и може да се разширява при необходимост, но без фрагментацията, характерна за Skia.
Горният слой — е графът за рендиране, в който Flutter Engine преобразува командите на Canvas API. Impeller приема Display List (списък с команди за рисуване) и изгражда от него граф на зависимостите на операциите. Графът се оптимизира: премахват се ненужни преминавания за рендиране, обединяват се операции с еднакво GPU състояние. След това графът се компилира в последователност от извиквания на Vulkan/Metal, използвайки предварително създадени pipeline-ове.
Всеки кадър преминава през фиксиран конвейер: Display List → граф за рендиране → компилация на графа → изпращане на GPU команди. Допълнителни преминавания могат да бъдат добавени за пост-ефекти (размазване, сенки) или подготовка на буфера за дълбочина. Времето на кадър в Impeller е по-предвидимо, отколкото в Skia, тъй като липсват недетерминистични забавяния за компилация на шейдъри.
Сравнението на Impeller и Skia показва разлики в подхода към рендирането. Skia — е универсална 2D библиотека за общо предназначение, докато Impeller — е специализиран механизъм за Flutter, оптимизиран за нуждите на мобилния UI.
| Параметър | Skia | Impeller |
|---|---|---|
| Шейдъри | Компилация по време на изпълнение | Offline компилация (build time) |
| Shader jank | 50–200 ms за първия кадър | Липсва (0 ms) |
| Формат на шейдъри | Собствен (SkSL) | SPIR-V (универсален) |
| GPU backend-ове | OpenGL, Vulkan, Metal | Vulkan, Metal, Direct3D 12 |
| Консумация на памет | Висока (временни текстури) | Паметови пулове, до -40% |
| Платформи | Android, iOS, Web, Desktop | Android, iOS, Desktop |
| Статус | Стабилен (основен) | Preview (замества Skia) |
Ключовата разлика — подходът към шейдърите. Skia компилира шейдърите в момента на използване, създавайки shader jank при първото рендиране на непознати ефекти. Impeller елиминира това чрез offline компилация. Също така Skia поддържа OpenGL, което е необходимо за уеб версията на Flutter, но Impeller се отказва от OpenGL в полза на по-модерни API, което дава по-добра производителност на мобилни устройства.
За Flutter приложения преминаването към Impeller не изисква промяна на кода. Impeller имплементира същия Canvas API като Skia, така че всички widget-ове, анимации и персонализирани рисунки работят по същия начин. Обратната съвместимост се гарантира на ниво Flutter Engine — механизмът избира renderer (Skia или Impeller) във фазата на инициализация на приложението.
Impeller предоставя няколко измерими предимства пред Skia, които пряко влияят на потребителското изживяване и производителността на Flutter приложенията.
Shader jank — основният проблем на Skia, който Impeller напълно решава. Когато Flutter приложение показва нов екран с градиенти, маски или нестандартни blend-ове, Skia компилира шейдърите по време на анимацията, което води до пропускане на кадри. Impeller компилира всички шейдъри във фазата на изграждане, така че първият кадър се рендира също толкова бързо, колкото и следващите. На устройства с бавен GPU (MediaTek Helio, Qualcomm 400 series) разликата е особено забележима — до 200 ms забавяне за всеки нов тип ефект в Skia срещу 0 ms в Impeller.
Impeller използва ресурсни пулове за управление на GPU паметта. В Skia всеки кадър може да създава нови текстури за временни повърхности, особено при рендиране с прозрачност или използване на saveLayer. Impeller повторно използва текстури между кадрите, което намалява пиковата консумация на памет с 30–40% на Android и до 25% на iOS. Това е особено важно за приложения с дълги списъци и анимации, където Skia можеше да причинява OOM грешки на устройства с 2 GB RAM.
В Skia времето за рендиране на кадър може да варира в зависимост от това кои шейдъри вече са компилирани. Първият кадър с нов ефект може да отнеме 50–200 ms, докато следващите — 3–5 ms. Тази непредвидимост затруднява оптимизацията и тестването. Impeller осигурява равномерно време на кадър, тъй като всички шейдъри вече са компилирани и разпределението на паметта е предвидимо. Flutter Engine с Impeller може по-точно да изчислява бюджетa от време за всеки кадър.
Impeller работи директно с Vulkan (Android), Metal (iOS) и Direct3D 12 (Windows), без слоя OpenGL. Това предоставя няколко предимства: по-ниска латентност на драйвера (до 50% по-малко отколкото през OpenGL), директен контрол над GPU паметта и достъп до съвременни възможности (tile-based GPU архитектура, GPU-driven rendering). OpenGL вече не се развива и неговите драйвери на мобилни устройства често се превръщат в тясно място за производителността.
Impeller е в активна фаза на разработка и е достъпен в каналите Flutter Master и Beta. От Flutter 3.16 Impeller е включен по подразбиране на iOS, а на Android — опционално чрез конфигурационен флаг. Пълната замяна на Skia с Impeller се очаква в една от стабилните версии на Flutter през 2026 г.
На iOS Impeller работи чрез Metal и е включен по подразбиране от Flutter 3.16. Екипът на Flutter препоръчва тестване на приложения на Impeller и докладване на проблеми. За връщане към Skia се използва флагът Impeller във файла Info.plist: FlutterEnableImpeller = NO. Според данни на Flutter Team, 92% от приложенията на iOS работят на Impeller без видими регресии, а производителността на анимациите се подобрява с 25–40%.
На Android Impeller работи чрез Vulkan. За включване в AndroidManifest.xml се добавя мета-таг: io.flutter.embedded_views_preview. Екипът на Flutter продължава оптимизацията на Impeller за различни GPU архитектури (Adreno, Mali, PowerVR). Основното предизвикателство на Android е поддръжката на устройства без Vulkan (Android < 7.0 или стари GPU). За такива устройства ще се използва резервен backend на Skia или Impeller с софтуерна растеризация.
На Windows Impeller работи чрез Direct3D 12 (включен във Flutter Master). На macOS и Linux — съответно чрез Metal и Vulkan. За Web Impeller не е планиран, тъй като уеб версията на Flutter използва CanvasKit (Skia чрез WebAssembly) и shader jank не е критичен проблем поради различния механизъм за компилация на шейдъри в браузъра. Уеб версията ще продължи да използва Skia.
Google публикува пътната карта на Impeller: 2024 — Impeller по подразбиране на iOS; 2025 — Impeller по подразбиране на Android и Windows; 2026 — пълно премахване на Skia от Flutter Engine. След това Flutter ще използва Impeller като единствен механизъм за рендиране, което ще опрости поддръжката, ще намали размера на механизма и ще подобри производителността на всички платформи.
Често задавани въпроси
На iOS Impeller е включен по подразбиране от Flutter 3.16. На Android добавете в AndroidManifest.xml мета-таг io.flutter.embedded_views_preview със стойност true. На Windows използвайте флага --enable-impeller при стартиране. Във всички случаи може да бъде принудително включен чрез FlutterEngine в Dart код.
Skia работи, но има фундаментални проблеми: shader jank (50–200 ms забавяне за компилация на шейдъри), висока консумация на памет и ограничения на архитектурата OpenGL. Impeller е проектиран специално за Flutter и премахва тези проблеми чрез offline компилация на шейдъри и паметови пулове.
Да, Impeller имплементира същия Canvas API като Skia. Всички стандартни Flutter widget-ове — текст, изображения, анимации, персонализирани paint-ове — работят на Impeller без промени. Обратната съвместимост се гарантира на ниво Flutter Engine и преходът е прозрачен за разработчика.
Не, приложението използва един механизъм за рендиране наведнъж. Изборът се прави при инициализация на Flutter Engine чрез флаг. Превключването между Skia и Impeller по време на изпълнение на приложението е невъзможно — renderer-ът се фиксира преди създаването на първия екземпляр на FlutterEngine.
Skia ще продължи да съществува като самостоятелна библиотека на Google за Chrome, Android и други проекти. В Flutter Skia ще бъде заменена от Impeller като основен renderer. Skia ще остане за уеб версията на Flutter (чрез CanvasKit) и като резервен вариант за устройства без поддръжка на Vulkan/Metal.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.