Proč řešit výkon u Flutteru a React Native
Flutter i React Native umožňují doručovat multiplatformní mobilní aplikace s nativním vzhledem a uživatelským zážitkem. Přestože oba přístupy sdílí některé koncepty (hot reload, komponentový model, bohatý ekosystém), zásadně se liší v architektuře vykreslování, běhovém prostředí i způsobu volání nativních API. Cílem tohoto článku je srovnat výkonnostní charakteristiky z hlediska latence vstupu, plynulosti animací, propustnosti uživatelského rozhraní (UI), startovacího času, paměťových nároků, velikosti binárky a nákladů na integraci nativních modulů – a navrhnout praktické optimalizační postupy pro obě technologie.
Architektura vykreslování a její dopad na výkon
- Flutter: využívá vlastní renderovací engine (Skia, nově Impeller pro Metal/Vulkan), který vykresluje celé uživatelské rozhraní do grafického plátna. Widgety jsou čistě deklarativní, přičemž výsledkem je strom elementů → RenderObject → rasterizace. Díky vlastnímu enginu Flutter obchází nativní widgety operačních systémů a dosahuje konzistentního chování a predikovatelného frame pacingu.
- React Native: historicky využíval bridge (JavaScript <→ nativní vrstva), který převáděl JSON zprávy mezi světy. Nová architektura (Fabric + JSI + TurboModules) odstraňuje serializaci přes bridge, zrychluje synchronizační body a zlepšuje determinismus. RN renderuje skrze nativní primitiva (UIView/Android View), což přináší lepší adaptaci na platformu, ale větší heterogenitu výkonu.
Startovací čas (cold start) a warm start
- Flutter: AOT kompilace Dart kódu snižuje interpretativní režii; cold start ovlivňuje inicializace engine a načtení shaderů. Impeller redukuje nutnost kompilace shaderů za běhu (nižší jank při prvních animacích).
- React Native: s Hermes (optimalizovaný JavaScript engine) a překomilovanými bytykódy klesá inicializační náklad a paměťová spotřeba. Fabric minimalizuje čas potřebný k vytvoření stromu nativních view. Přesto bývá cold start citlivější na velikost bundlu a lazy-loading modulů.
Plynulost UI: FPS, frame pacing a vstupní latence
- Flutter cílí na 60/120 FPS s oddělením UI a raster threadu; pokud Dart kód blokuje UI thread, animace trpí. Impeller snižuje variance renderu a stabilizuje frame pacing, zejména u složitých shaderů a maskování.
- React Native: s Fabric/JSI a synchronním layoutem v C++ se snižuje režie při „commit“ fázi. Latence gest výrazně klesá, zejména při použití react-native-reanimated a Gesture Handler, které přesouvají část práce mimo JavaScript event loop.
Animace a gesta
- Flutter: nabízí bohatý animační systém (tweeny, fyzikální simulace, implicitní/explicitní animace), který běží deterministicky nad DPM (Dart UI). Výkon animací závisí na efektivitě rebuildů a rozumné granularitě widgetů.
- React Native: Reanimated 2+ umožňuje tzv. worklets přímo na UI threadu; animace tak nemusí čekat na JavaScript. U komplexních scén je výkon srovnatelný s Flutterm, pokud je minimalizován počet re-renderů.
Propustnost layoutu a složitost stromu
- Flutter: layout probíhá v jednom grafu (měření/layout/paint) mimo nativní hierarchii. Výkon degraduje s hlubokými stromy a častým používáním global keys. RepaintBoundary a AutomaticKeepAlive jsou klíčové pro izolaci a optimalizaci vykreslování.
- React Native: Fabric používá Yoga (Flexbox). Velmi široké či hluboké stromy mohou způsobit více průchodů layoutem; optimalizace zahrnují memoizaci (React.memo), rozumné zanoření a windowing seznamů.
Grafika, text a rasterizace
- Flutter: Skia/Impeller poskytují silnou kontrolu nad textem, vektory, klipy, maskami a efekty; cena je větší velikost binárky a nutnost dbát na správu offscreen layers a kompozici.
- React Native: spoléhá na nativní textové vykreslování a kompozici view, což znamená dobrý výchozí výkon pro standardní UI, ale vyšší náklady na extrémní vizuální efekty (custom canvas → Skia RN, OpenGL nebo platformní kreslení).
Paměťová náročnost a správa paměti (GC)
- Flutter: Dart používá generational garbage collector, který je rychlý, nicméně vytváření mnoha krátkodobých objektů v horké smyčce (např. v build()) může způsobit mikro-stutter; řešením je recyklace objektů a rozumná granularita widgetů.
- React Native: Hermes má kompaktní reprezentaci objektů a efektivní garbage collector; je však třeba dávat pozor na úniky paměti způsobené referenčními cykly mezi JavaScriptem a nativními vrstvami a na velké in-memory seznamy bez windowingu.
Velikost binárky (APK/IPA) a doba stahování
- Flutter: obsahuje engine a Skia/Impeller, což znamená větší základní velikost, zejména u „hello world“ aplikací. Pro produkci je nutné použít R8/ProGuard (Android), bitcode/strip (iOS), asset kompresi a rozdělení balíčků per ABI.
- React Native: závisí na velikosti JavaScript bundlu a použitých nativních knihovnách; Hermes s bytykódy snižuje runtime náklady a někdy i výslednou velikost.
Volání nativních API a I/O
- Flutter: využívá platform channels pro binární zprávy; režie je nízká při rozumné granularitě volání. Pro intenzivní streaming bývá vhodné použít event channels nebo FFI s C/C++ knihovnami.
- React Native: dříve bridge limitoval průchodnost dat, nová architektura JSI/TurboModules odstraňuje serializaci, zlepšuje latenci a umožňuje přímé C++ bindingy. Pro I/O operace je vhodné preferovat pozadí vlákna a řízení backpressure.
Vícevláknové zpracování a paralelismus
- Flutter: používá Isolates pro CPU-vázanou práci; komunikace probíhá přes porty (bez sdílené paměti). Raster/UI thread jsou oddělené; blokování hlavního isolatu znamená drop frame.
- React Native: rozdělení na UI thread/render thread/JavaScript thread; nová architektura umožňuje posunout část práce do C++/UI threadu (worklets). Pro těžké výpočty se doporučuje využití nativních modulů.
Seznamy, virtualizace a nekonečné feedy
- Flutter: využívá ListView.builder, SliverList, SliverGrid a ScrollablePositionedList. Při komplexních položkách je vhodné užívat const widgety, AutomaticKeepAlive a RepaintBoundary.
- React Native: nabízí FlatList, SectionList s nastavením windowSize, getItemLayout a removeClippedSubviews. Plynulost závisí na správném klíčování, memoizaci item rendereru a stabilních referencích.
Profilování a diagnostika výkonu
- Flutter: nástroj DevTools (timeline, statistiky rasterizeru, shader warmup), dart:developer (Timeline), flutter run –profile, tracing v Systrace.
- React Native: nástroje jako Flipper (síť, layout, výkon), Hermes profiler, Systrace/Perfetto, react-devtools a speciální nástroje pro Fabric/JSI.
Energetická efektivita (battery budget)
- Flutter: stabilní frame pacing snižuje přemalovávání; je však třeba dávat pozor na animace běžící na pozadí, časté volání setState a vysokou frekvenci timerů.
- React Native: doporučuje minimalizovat zátěž JavaScript event loopu, využívat reanimated worklets a debounce. Preferujte nativní animace a přesun těžkých úloh do nativních modulů.
Modelové benchmarky a interpretace
- UI microbench: 1) navigace mezi obrazovkami, 2) 10 000 položek ve scrollu, 3) animace 60 fps se stínem a ořezem. Sledujte 95. a 99. percentil frame time, počet ztracených snímků (dropped frames), čas CPU/GPU a pauzy garbage collectoru.
- Start-up: cold/warm start (Time To Interactive), inicializace modulů a načtení zdrojů. Vyhodnocujte také total blocking time (TBT) na úrovni JavaScriptu/Dartu.
- I/O a bridge: simulujte 1000 volání nativních API za sekundu; měřte latenci, jitter a využití CPU v obou světech.
Optimalizační postupy pro Flutter
- Aktivujte Impeller na iOS i Androidu, proveďte shader warmup pro často používané efekty.
- Rozumně využívejte const konstruktory, ValueListenableBuilder/Selector pro lokální rebuildy a RepaintBoundary u složitých podsestav.
- Offload CPU-vázané úlohy na Isolates; u streamingového I/O použijte compute() nebo vlastní isolate.
- Profilujte layout, paint a raster v DevTools a eliminujte nadměrné přemalování (např. pomocí debug repaint rainbow).
Optimalizační postupy pro React Native
- Přejděte na novou architekturu (Fabric + JSI + TurboModules) a využívejte Hermes.
- Realizujte animace přes react-native-reanimated a Gesture Handler; minimalizujte závislost na JavaScript event loopu.
- Memoizujte komponenty (React.memo, useMemo, useCallback), stabilizujte props a klíče.
- U rozsáhlých seznamů používejte windowing, getItemLayout a removeClippedSubviews.
Velké grafy, mapy a 3D
- Flutter: pro náročné vizualizace doporučujeme použít CustomPainter, SceneBuilder a případně FFI (C/C++). Mapy: preferujte nativní integrace s platformními SDK přes platform channels.
- React Native: pro graficky náročné scény lze využít react-native-skia nebo WebGL/Vulkan bindingy; mapy implementujte přes nativní SDK s minimalizací prop-drillingu.
Stabilita frame pacingu vs. nativní vzhled
Flutter díky vlastnímu enginu nabízí velmi stabilní a konzistentní frame pacing napříč zařízeními; naopak cena je větší velikost balíčku a někdy méně „zcela nativní“ pocit u některých komponent (to je řešitelné knihovnami Material, Cupertino a třetích stran). React Native těží z nativních komponent a přirozených interakcí operačního systému, avšak u heterogenních zařízení vyžaduje více péče o ladění výkonu (zejména z minulosti s bridgem; Fabric však většinu omezení výrazně zmírňuje).
Bezpečnost a sandbox výkonu
- Flutter: FFI zvyšuje výkon tam, kde je potřebná nativní knihovna; je nutné dbát na thread safety a životní cyklus engine.
- React Native: JSI C++ moduly umožňují psát vysoce výkonný kód blízko hardwaru; důležité je zajistit správnou správu paměti a kompatibilitu mezi platformami.
Jak vybrat technologii z pohledu výkonu
- Hodně animací, custom UI, konzistence na široké škále hardwaru: Flutter má výhodu díky vlastnímu renderingu a Impelleru.
- Silná integrace s nativními view a knihovnami, „platform-first“ UX: React Native s Fabric a Hermes je ideální volba, obzvlášť při využití reanimated.
- Těžké výpočty: obě technologie vyžadují přesun do nativních modulů či izolátů; rozdíly ve výkonu více závisí na kvalitě implementace než na frameworku.
Antipatterny a časté chyby
- Flutter: masivní rebuildy stromu způsobené změnami v nadřazených InheritedWidget; absence RepaintBoundary; synchronní I/O na UI isolatu; nadměrné používání GlobalKey.
- React Native: časté volání setState bez memoizace; těžké operace na JavaScript threadu; velké JS bundle bez kódového dělení; spoléhání na starý bridge při vysoké frekvenci volání.
Roadmapa a budoucí směry
- Flutter: další zlepšování Impelleru, redukce janku v první fázi běhu, optimalizace pro 120 Hz displeje a lepší interoperabilita s nativními poh



























