Flutter vs. React Native – srovnání výkonu
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 pocitem. 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ýkonové charakteristiky z hlediska latence vstupu, plynulosti animací, propustnosti 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: vlastní renderovací engine (Skia, nově Impeller pro Metal/Vulkan) vykresluje celé UI do plátna. Widgety jsou čistě deklarativní, ale výsledkem je strom elementů → RenderObject → rasterizace. Díky vlastnímu enginu Flutter obchází nativní widgety OS a dosahuje konzistentního chování a predikovatelného frame pacingu.
- React Native: historicky využíval bridge (JS <→ nativní), 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í overhead; cold start ovlivňuje inicializace engine + načtení shaderů. Impeller redukuje hity shader kompilace za běhu (nižší jank při prvních animacích).
- React Native: s Hermes (optimalizovaný JS engine) a pre-kompilovanými bytykódy klesá initialization cost a paměť. 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íluje 60/120 FPS s oddělením UI a raster threadu; pokud Dart kód blokuje UI thread, animace trpí. Impeller snižuje variability 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 overhead 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 JS event loop.
Animace a gesta
- Flutter: bohatý animační systém (tweeny, fyzikální simulace, implicitní/explicitní animace) běží deterministicky nad DPM (Dart UI). Animace závisí na efektivitě rebuildů a rozumné granularitě widgetů.
- React Native: Reanimated 2+ umožňuje tzv. worklets na UI threadu; animace tak nemusí čekat na JS. U komplexních scén je výkonnost srovnatelná s Flutterm, pokud je minimalizován počet re-renderů.
Propustnost layoutu a složitost stromu
- Flutter: layout probíhá v jednom grafu (measure/layout/paint) mimo nativní hierarchy. Výkon degraduje s hlubokými stromy a častými global keys. RepaintBoundary a AutomaticKeepAlive jsou klíčové pro izolaci.
- React Native: Fabric používá Yoga (Flexbox). Velmi široké/hluboké stromy mohou způsobit více průchodů layoutu; 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 velikost binárky a nutnost dbát na offscreen layers a kompozici.
- React Native: spoleh na nativní textový rendering a view kompozici znamená dobrý výchozí výkon pro standardní UI, ale dražší cost u extrémních efektů (custom canvas → Skia RN, GL, nebo platformní kreslení).
Paměťová náročnost a GC
- Flutter: Dart používá generational GC, 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 objektová recyklace a rozumná granularita widgetů.
- React Native: Hermes má kompaktní reprezentaci objektů a dobrý GC; pozor na leakující referenční cykly mezi JS a nativem a na velké in-memory seznamy bez windowingu.
Velikost binárky (APK/IPA) a doba stahování
- Flutter: obsahuje engine a Skia/Impeller → větší základní velikost, zejména u „hello world“. Pro produkci je nutné R8/ProGuard (Android), bitcode/strip (iOS), asset komprese a split per ABI.
- React Native: závisí na velikosti JS bundlu a použitých nativních knihovnách; Hermes s bytykódy snižuje runtime náklady a někdy i velikost.
Volání nativních API a I/O
- Flutter: platform channels přes binární zprávy; overhead je nízký při rozumné granularitě volání. Pro intenzivní streaming použijte event channels nebo FFI s C/C++ knihovnami.
- React Native: dříve bridge limitoval throughput; JSI/TurboModules odstraňují serializaci, zlepšují latenci a umožňují přímé C++ bindingy. Pro I/O preferujte background thread a backpressure.
Vícevláknové zpracování a paralelismus
- Flutter: Isolates pro CPU-bound práce; komunikace přes porty (bez sdílené paměti). Raster/UI jsou oddělené; blokování hlavního isolate = drop frame.
- React Native: UI thread/render thread/JS thread; s novou architekturou lze část práce posunout do C++/UI threadu (worklets), pro těžké výpočty použít nativní moduly.
Listy, virtualizace a nekonečné feedy
- Flutter: ListView.builder, SliverList, SliverGrid a ScrollablePositionedList. Při komplexních dlaždicích využívejte const widgety, AutomaticKeepAlive a RepaintBoundary.
- React Native: FlatList, SectionList s windowSize, getItemLayout, removeClippedSubviews. Plynulost stojí na správném klíčování, memoizaci item rendereru a stabilních referencích.
Profilování a diagnostika výkonu
- Flutter: DevTools (timeline, rasterizer stats, shader warmup), dart:developer (Timeline), flutter run –profile, tracing v Systrace.
- React Native: Flipper (network, layout, perf), Hermes profiler, Systrace/Perfetto, react-devtools, a nástroje pro Fabric/JSI.
Energetická efektivita (battery budget)
- Flutter: stabilní frame pacing snižuje re-rendering; pozor na animace běžící na pozadí, časté setState a vysokou frekvenci timers.
- React Native: minimalizujte zátěž JS smyčky, používejte reanimated worklets a debounce. Preferujte nativní animace a offloading těžkých úloh do nativu.
Modelové benchmarky a interpretace
- UI microbench: 1) navigace mezi obrazovkami, 2) 10k položek ve scrollu, 3) animace 60 fps se stínem a ořezem. Sledujte p95/p99 frame time, dropped frames, CPU/GPU time a GC pauzy.
- Start-up: cold/warm start (TTI), inicializace modulů a načtení zdrojů. Vyhodnocujte také TBT (total blocking time) na JS/Dart levelu.
- I/O a bridge: 1000 volání nativních API/sekundu; měřte latenci, jitter a CPU využití obou světů.
Optimalizační postupy pro Flutter
- Aktivujte Impeller na iOS/Android, proveďte shader warmup pro často používané efekty.
- Rozumně používejte const konstruktory, ValueListenableBuilder/Selector pro lokální rebuildy a RepaintBoundary u složitých podsestav.
- Offload CPU-bound na Isolates; u streaming I/O použijte compute() či vlastní isolate.
- Profilujte layout/paint/raster v DevTools a eliminujte přemalovávání (debug repaint rainbow).
Optimalizační postupy pro React Native
- Přejděte na novou architekturu (Fabric + JSI + TurboModules) a používejte Hermes.
- Animace přes react-native-reanimated a Gesture Handler; minimalizujte závislost na JS event loopu.
- Memoizujte komponenty (React.memo, useMemo, useCallback), stabilizujte props a klíče.
- U dlouhých seznamů využijte windowing, getItemLayout a removeClippedSubviews.
Velké grafy, mapy a 3D
- Flutter: pro náročné vizualizace využijte CustomPainter, SceneBuilder a případně FFI (C/C++). Mapy: doporučené nativní integrace s platformními SDK přes platform channels.
- React Native: pro graficky náročné scény použijte react-native-skia nebo WebGL/Vulkan bindingy; mapy 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; cenu představuje vyšší velikost balíčku a někdy „ne zcela nativní“ pocit u některých komponent (řešitelné Material/Cupertino/3rd party knihovnami). React Native těží z nativních komponent a přirozených interakcí OS, ale u heterogenních zařízení vyžaduje více péče o performance tuning (zejména v minulosti s bridgem; Fabric většinu limitů výrazně tlumí).
Bezpečnost a sandbox výkonu
- Flutter: FFI zvyšuje výkon tam, kde je třeba nativní knihovna; dbejte na thread safety a životní cyklus engine.
- React Native: JSI C++ moduly umožňují psát výkonný kód blízko kovu; pozor na správu paměti a kompatibilitu mezi platformami.
Jak vybrat technologii z pohledu výkonu
- Hodně animací, custom UI, konzistence na široké škále HW: 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 skvělá volba, obzvlášť při využití reanimated.
- Těžké výpočty: obě technologie vyžadují přesun do nativu/izolátů; výkonnost rozdílů závisí více na kvalitě implementace než na frameworku.
Antipatterny a časté chyby
- Flutter: masivní rebuildy stromu kvůli změnám nadřazených InheritedWidget; absence RepaintBoundary; synchronní I/O na UI isolate; mnoho GlobalKey.
- React Native: časté setState bez memoizace; těžké operace na JS threadu; velké JS bundly 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, menší jank v první fázi běhu, optimalizace pro 120 Hz a lepší interop s nativními pohledy.
- React Native: konsolidace nové architektury, širší adopce TurboModules, hlubší integrace profilovacích nástrojů a snižování velikosti bundlu.
Doporučení pro výkonnostní testy v praxi
- Definujte kritické scénáře: cold start, prvotní animace, scroll feedu, formuláře s validací, navigace mezi 3–5 obrazovkami.
- Měřte p95/p99 frame time, počet dropped frames, TTI/TTFB, CPU/GPU time, paměť (peak/resident), GC pauzy a velikost binárky.
- Automatizujte benchmarky na reálném HW (mid-tier Android, starší iPhone) a CI pipeline; sledujte regresní prahy.
Závěr: Výkon je výsledkem architektury i disciplíny
Flutter i React Native mohou doručit plynulá UI a špičkový uživatelský zážitek. Flutter sází na vlastní renderovací engine, čímž nabízí konzistentní frame pacing a kontrolu nad grafikou. React Native s novou architekturou Fabric/JSI a enginem Hermes odstranil historické limity bridge a přiblížil se Fluttru ve většině scénářů – s bonusem nativních komponent. Konečný výkon závisí primárně na volbě architektury aplikace, optimalizaci stromu, eliminaci blokujících operací a pečlivé práci s animacemi, seznamy a I/O. Správně navržené aplikace v obou technologiích dosahují prakticky nativního chování; volba technologie by se proto měla řídit také týmem, ekosystémem, požadovanou úrovní „platform look & feel“ a nároky na specifická nativní API.