RenderObject Tree: co to je, princip vykreslování a role ve Flutter

Autor: IT Sectr Publikováno: 2026-07-01 Doba čtení: 9 min

RenderObject Tree — je třetí úroveň hierarchie ve Flutter, zodpovědná za skutečné vykreslování rozhraní na obrazovce. Každý uzel tohoto stromu provádí výpočet rozměrů (layout) a kreslení (painting), převádějící konfiguraci widgetů na pixely. Na rozdíl od Widget Tree je RenderObject Tree vytvořen jednou a aktualizuje se pouze při změně geometrie nebo vzhledu. Podle Flutter API Reference, 2025 efektivita RenderObject Tree přímo určuje plynulost animací a rychlost odezvy aplikace.

Hlavní body

  • RenderObject Tree — hierarchie objektů vykreslování, které vypočítávají rozměry a kreslí rozhraní na obrazovce.
  • Každý RenderObject provádí dvě fáze: layout (určení rozměrů a pozic) a paint (kreslení pixelů).
  • RenderObject Tree je vytvořen z Element Tree a synchronizován s ním prostřednictvím prvků.
  • RepaintBoundary izoluje část stromu pro lokální překreslení bez ovlivnění celé obrazovky.
  • Výkon RenderObject Tree závisí na hloubce, počtu vrstev a frekvenci překreslování.

Co je RenderObject Tree ve Flutter?

RenderObject Tree — je hierarchická struktura objektů vykreslování, která je skutečnou reprezentací rozhraní v paměti. Každý RenderObject zná své rozměry, polohu na obrazovce a umí se nakreslit. Na rozdíl od widgetů, které jsou lehké a mohou být znovu vytvářeny stokrát za sekundu, RenderObject — je těžký objekt s přímým přístupem ke grafické pipeline.

Od konfigurace k vykreslování

Cesta od widgetu k pixelům prochází třemi fázemi: Widget Tree popisuje, co by mělo být na obrazovce; Element Tree spravuje životní cyklus; RenderObject Tree provádí skutečnou práci. Každý RenderObjectWidget (např. Padding, Transform, CustomPaint) vytváří RenderObject, který je přidán do stromu vykreslování. RenderBox — nejrozšířenější typ RenderObject, používaný pro 99% standardních widgetů.

Architektura RenderObject

RenderObject — je abstraktní třída definující rozhraní pro layout a paint. Obsahuje odkazy na rodičovský RenderObject a podřízené objekty, stejně jako abstraktní metody: performLayout, paint a hitTest. Každý konkrétní RenderObject implementuje tyto metody podle svého chování: RenderFlex rozděluje prostor mezi podřízené prvky, RenderImage zobrazuje obrázek, RenderParagraph zobrazuje text.

dart
abstract class RenderObject {
  RenderObject? parent;
  Constraints constraints;
  ParentData? parentData;
  bool _needsLayout = true;
  bool _needsPaint = true;

  void performLayout();
  void paint(PaintingContext context, Offset offset);
}

V této zjednodušené struktuře obsahuje RenderObject příznaky _needsLayout a _needsPaint, které označují objekt jako vyžadující aktualizaci. Když se Widget Tree změní, Element Tree označí odpovídající RenderObject jako „špinavý„ pro layout nebo paint a při příštím snímku Flutter provede pouze nezbytné operace.

Dvě fáze RenderObject: layout a paint

Každý RenderObject provádí dvě klíčové fáze: layout (určení rozměrů a pozic) a paint (kreslení). Tyto fáze se provádějí v přísném pořadí: nejprve layout pro celý strom, poté paint. Fáze paint může být vynechána, pokud se layout nezměnil, což šetří prostředky GPU.

Fáze layout: omezení a rozměry

Během layoutu Flutter předává omezení (constraints) shora dolů přes RenderObject Tree. Každý rodič nastavuje pro podřízený objekt minimální a maximální šířku a výšku. Podřízený objekt vypočítá svou velikost v rámci těchto omezení a vrátí ji rodiči. Tento proces se nazývá „downward pass„ (předávání omezení dolů) a „upward pass„ (předávání rozměrů nahoru).

  • BoxConstraints — nejběžnější typ omezení: minWidth, maxWidth, minHeight, maxHeight.
  • SliverConstraints — používá se v ScrollView pro virtualizaci: ke standardním omezením se přidává informace o posouvání.
  • RenderSliverMultiBoxAdaptor — spravuje layout virtualizovaných seznamů, vytváří RenderObject pouze pro viditelné prvky.

Fáze paint: zobrazení na obrazovce

Po dokončení layoutu Flutter provede paint — kreslení každého RenderObject. Rodič vytvoří PaintingContext, předá ho podřízeným objektům a určí posun (offset). Každý RenderObject se kreslí na Canvas pomocí grafických primitiv: obdélníky, kruhy, text, obrázky a transformace. Canvas přímo komunikuje s Skia nebo Impeller.

Označování špinavých uzlů

Flutter používá mechanismus „špinavých„ uzlů k minimalizaci práce. Když se změní pouze velikost jednoho RenderObject, Flutter nepřepočítává layout celého stromu — označí změněný uzel a jeho možné předky až k nejbližšímu RenderBox s pevnou velikostí. Podobně při změně vzhledu se označí pouze paint bez opakování layoutu.

Typy RenderObject ve Flutter

Flutter poskytuje několik kategorií RenderObject pro různé úkoly: RenderBox pro standardní obdélníkové prvky, RenderSliver pro posouvatelné oblasti a vlastní RenderObject pro nestandardní vykreslování přes CustomPainter. Každý typ je optimalizován pro svou roli ve stromu vykreslování.

RenderBox a jeho podtypy

RenderBox — základní třída pro obdélníkové prvky rozhraní. Jeho podtypy: RenderPadding (přidává mezery), RenderTransform (aplikuje transformace), RenderFlex (implementuje Row a Column), RenderStack (vrstvení prvků), RenderImage (zobrazení obrázků), RenderParagraph (zobrazení textu). Každý podtyp přepisuje performLayout a paint pro svou logiku.

RenderSliver a virtualizace

RenderSliver — je typ RenderObject pro práci s posouvatelnými oblastmi. Na rozdíl od RenderBox používá Sliver SliverConstraints, které zahrnují informace o viditelné oblasti (viewport). RenderSliverList a RenderSliverGrid vytvářejí RenderObject pouze pro prvky ve viditelné oblasti, což umožňuje zpracování seznamů s miliony záznamů.

Vlastní RenderObject přes CustomPainter

Pro nestandardní grafiku použijte CustomPaint a CustomPainter. CustomPaint vytváří RenderCustomPaint, který volá metody paint v CustomPainter. To umožňuje kreslení libovolných tvarů, grafů a animací s plnou kontrolou nad Canvas. Podle Flutter Team je CustomPainter efektivnější než vnořené standardní widgety pro komplexní vektorovou grafiku.

dart
class CirclePainter extends CustomPainter {
  final Color color;

  CirclePainter({required this.color});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = color;
    canvas.drawCircle(
      Offset(size.width / 2, size.height / 2),
      size.width / 3,
      paint,
    );
  }

  @override
  bool shouldRepaint(CirclePainter oldDelegate) =>
    oldDelegate.color != color;
}

V tomto příkladu CirclePainter kreslí kruh na Canvas. Metoda shouldRepaint vrací true pouze při změně barvy, což zabraňuje zbytečnému překreslování. CustomPainter by měl být co nejlehčí — všechny těžké výpočty provádějte mimo metody paint.

RenderObject Tree je vytvořen z Element Tree prostřednictvím mechanismu RenderObjectWidget. Každý RenderObjectWidget (Padding, Transform, CustomPaint) vytváří RenderObjectElement, který vytváří a spravuje odpovídající RenderObject. Prvek funguje jako prostředník: předává konfiguraci z widgetu do RenderObject a informuje RenderObject o změnách.

Vytvoření RenderObject z prvku

Když je RenderObjectElement připojen, zavolá metodu createRenderObject svého widgetu. Widget vytvoří instanci RenderObject a vrátí ji prvku. Prvek vloží RenderObject do RenderObject Tree zavoláním metody insertChildLayout u rodičovského RenderObject. Tento proces probíhá pouze při prvním připojení — při následných aktualizacích prvek jednoduše aktualizuje parametry existujícího RenderObject.

Synchronizace přes updateRenderObject

Když se konfigurace widgetu změní (např. změní se hodnota padding), prvek zavolá metodu updateRenderObject, která předá novou konfiguraci existujícímu RenderObject. RenderObject se označí jako „špinavý„ pro layout nebo paint a při příštím snímku framework provede potřebné aktualizace.

Odstranění RenderObject

Při odpojení prvku se zavolá metoda unmount, která odstraní RenderObject z RenderObject Tree a uvolní prostředky. RenderObject.remove se volá pro odpojení od rodiče, poté může být objekt shromážděn garbage collectorem. Flutter zaručuje, že RenderObject nevisí ve stromu bez odpovídajícího prvku.

RepaintBoundary a izolace vykreslování

RepaintBoundary — je widget, který vytváří samostatnou vrstvu pro vykreslování svého obsahu. Když se obsah RepaintBoundary změní, překreslí se pouze tato vrstva a ostatní části obrazovky zůstanou nezměněny. RepaintBoundary je zvláště užitečný pro animace, přehrávače videa, interaktivní grafy a další často aktualizované prvky.

Jak RepaintBoundary funguje

Základem RepaintBoundary je RenderRepaintBoundary — speciální RenderObject, který vytváří samostatný PictureLayer. Při prvním vykreslení RenderRepaintBoundary zaznamená grafické příkazy do této vrstvy. Při následných aktualizacích, pokud se změnil pouze obsah uvnitř RepaintBoundary, Flutter překreslí pouze tuto vrstvu, ne celou obrazovku. Ostatní vrstvy zůstávají nezměněny a jsou znovu použity.

Kdy použít RepaintBoundary

Ne každý widget potřebuje RepaintBoundary. Použijte ho, když se část rozhraní aktualizuje s vysokou frekvencí (60 FPS a více), zatímco zbytek obrazovky je statický. Typické příklady: animovaný indikátor načítání, přehrávač videa, herní Canvas, CustomPainter s častým překreslováním. Pro statický text nebo tlačítka je RepaintBoundary zbytečný a pouze zvyšuje spotřebu paměti.

ScénářDoporučeníDůvod
AnimaceZabalit do RepaintBoundaryIzoluje často aktualizovanou oblast
Posouvatelný seznamNení nutnéListView automaticky používá vrstvy
Statický textNení nutnéŽádné časté překreslování
CustomPainterDoporučenoČasté překreslování grafiky

Optimalizace RenderObject Tree pro výkon

Výkon RenderObject Tree závisí na počtu uzlů, hloubce stromu a frekvenci překreslování. Nástroje Flutter DevTools (karta „Rendering„) umožňují analýzu RenderObject Tree v reálném čase: počet repaint, čas layout a paint, počet vrstev a jejich velikosti. Pravidelná analýza pomáhá identifikovat úzká místa.

Vyhněte se nadměrnému overdraw

Overdraw — je situace, kdy je jeden pixel kreslen několikrát za snímek. Například když se poloprůhledný widget překrývá s jiným, GPU kreslí obě vrstvy. Používejte opaque příznaky (Container s color místo decoration) pro neprůhledné prvky, aby Flutter přeskočil neviditelné vrstvy. Podle Flutter Team může snížení overdraw zkrátit čas paint až o 30%.

Minimalizujte počet vrstev

Každý RepaintBoundary a některé widgety (Opacity, ClipRRect, Transform) vytvářejí samostatnou vrstvu (PictureLayer). Příliš mnoho vrstev zvyšuje čas kompozice. Používejte seskupování: místo několika Opacity na jednotlivých widgetech aplikujte jeden Opacity na kontejner. Místo ClipRRect na každém prvku použijte ClipRRect na společném kontejneru.

Používejte const-konstruktory

Když je widget deklarován jako const, Flutter ví, že se jeho konfigurace nezmění a může znovu použít odpovídající RenderObject bez znovuvytvoření. Const-konstruktory snižují zatížení garbage collectoru a zrychlují první snímek. Používejte const pro widgety s pevnými parametry: ikony, nadpisy, dekorativní prvky.

dart
const Text("Název", style: TextStyle(fontSize: 24));
const Icon(Icons.home, color: Colors.blue);
const SizedBox.shrink();

Často kladené otázky

Čím se RenderObject Tree liší od Widget Tree?

Widget Tree — je lehká konfigurace rozhraní, která se znovu vytváří při každém rebuild. RenderObject Tree — je těžký strom objektů vykreslování, který je zachován a aktualizuje se pouze při změně geometrie nebo vzhledu.

Jak vidět RenderObject Tree v debuggeru?

Použijte Flutter DevTools — karta „Rendering„. Uvidíte vrstvy vykreslování, čas layout a paint, stejně jako podrobné informace o každém RenderObject: rozměry, constraints, příznaky potřeby aktualizace.

Co je dirty RenderObject?

Dirty — je RenderObject, který je označen jako vyžadující aktualizaci. Příznak _needsLayout nebo _needsPaint se nastaví při změně konfigurace a Flutter provede layout nebo paint pro tento uzel v příštím snímku.

Mohu vytvořit vlastní RenderObject?

Ano, vytvořte podtřídu RenderBox a přepište metody performLayout a paint. Použijte RenderObjectWidget pro vložení vlastního RenderObject do Widget Tree. Toto je pokročilá technika pro nestandardní vykreslování.

Jak RepaintBoundary ovlivňuje RenderObject Tree?

RepaintBoundary vytváří RenderRepaintBoundary, který izoluje část RenderObject Tree do samostatné vrstvy. Při změně obsahu se překreslí pouze tato vrstva a zbytek stromu zůstane nezměněn.

Shrnutí

  • RenderObject Tree — třetí úroveň architektury Flutter, zodpovědná za layout a paint každého prvku rozhraní.
  • Každý RenderObject provádí dvě fáze: layout (výpočet rozměrů a pozic) a paint (kreslení pixelů přes Canvas).
  • RenderBox — základní typ pro standardní prvky, RenderSliver — pro virtualizaci posouvatelných seznamů.
  • RenderObject Tree je synchronizován s Element Tree přes RenderObjectElement, který vytváří a aktualizuje RenderObject.
  • RepaintBoundary izoluje část stromu do samostatné vrstvy, zabraňující úplnému překreslení obrazovky při lokálních změnách.
  • Výkon závisí na hloubce stromu, počtu vrstev, overdraw a používání const-konstruktorů.
  • Flutter DevTools poskytuje nástroje pro analýzu RenderObject Tree: čas layout, čas paint, počet vrstev a repaint.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také