RenderObject Tree: ano ito, prinsipyo ng pag-render at papel sa Flutter

May-akda: IT Sectr Nai-publish: 2026-07-01 Oras ng pagbabasa: 9 min

RenderObject Tree — ay ang ikatlong antas ng hierarchy sa Flutter, na responsable para sa aktwal na pag-render ng interface sa screen. Ang bawat node ng punong ito ay nagsasagawa ng pagkalkula ng mga sukat (layout) at pagguhit (painting), na ginagawang pixel ang configuration ng widget. Hindi tulad ng Widget Tree, ang RenderObject Tree ay ginagawa nang isang beses at ina-update lamang kapag nagbago ang geometry o anyo. Ayon sa Flutter API Reference, 2025, ang kahusayan ng RenderObject Tree ay direktang tumutukoy sa kinis ng mga animation at bilis ng pagtugon ng application.

Mga pangunahing punto

  • RenderObject Tree — hierarchy ng mga object ng pag-render na nagkalkula ng mga sukat at gumuguhit ng interface sa screen.
  • Bawat RenderObject ay nagsasagawa ng dalawang phase: layout (pagtukoy ng mga sukat at posisyon) at paint (pagguhit ng mga pixel).
  • RenderObject Tree ay ginagawa mula sa Element Tree at naka-sync dito sa pamamagitan ng mga elemento.
  • RepaintBoundary ay naghihiwalay ng bahagi ng puno para sa lokal na pag-redraw nang hindi naaapektuhan ang buong screen.
  • Performance ng RenderObject Tree ay depende sa lalim, bilang ng mga layer at dalas ng pag-redraw.

Ano ang RenderObject Tree sa Flutter?

RenderObject Tree — ay isang hierarchical na istraktura ng mga object ng pag-render na siyang aktwal na representasyon ng interface sa memorya. Ang bawat RenderObject ay alam ang mga sukat nito, posisyon sa screen at kayang gumuhit ng sarili nito. Hindi tulad ng mga widget na magaan at maaaring muling gawin nang daan-daang beses bawat segundo, ang RenderObject — ay isang mabigat na object na may direktang access sa graphics pipeline.

Mula sa configuration patungo sa pag-render

Ang landas mula widget patungo sa pixel ay dumadaan sa tatlong yugto: Inilalarawan ng Widget Tree kung ano ang dapat nasa screen; Pinamamahalaan ng Element Tree ang lifecycle; RenderObject Tree ang gumagawa ng aktwal na trabaho. Bawat RenderObjectWidget (hal. Padding, Transform, CustomPaint) ay gumagawa ng RenderObject na idinaragdag sa puno ng pag-render. RenderBox — ang pinakakaraniwang uri ng RenderObject, ginagamit para sa 99% ng mga standard na widget.

Arkitektura ng RenderObject

RenderObject — ay isang abstract na klase na tumutukoy sa interface para sa layout at paint. Naglalaman ito ng mga reference sa parent na RenderObject at mga child object, pati na rin ang mga abstract na pamamaraan: performLayout, paint at hitTest. Bawat konkretong RenderObject ay nagpapatupad ng mga pamamaraang ito ayon sa kanyang pag-uugali: Ipinamamahagi ng RenderFlex ang espasyo sa pagitan ng mga child element, Ipinapakita ng RenderImage ang larawan, Ipinapakita ng RenderParagraph ang teksto.

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

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

Sa pinasimpleng istrakturang ito, ang RenderObject ay naglalaman ng mga flag na _needsLayout at _needsPaint na nagmamarka ng object bilang nangangailangan ng update. Kapag nagbago ang Widget Tree, minamarkahan ng Element Tree ang kaukulang RenderObject bilang "marumi" para sa layout o paint, at sa susunod na frame ay ginagawa lamang ng Flutter ang mga kinakailangang operasyon.

Dalawang phase ng RenderObject: layout at paint

Bawat RenderObject ay nagsasagawa ng dalawang pangunahing phase: layout (pagtukoy ng mga sukat at posisyon) at paint (pagguhit). Ang mga phase na ito ay isinasagawa sa mahigpit na pagkakasunud-sunod: una layout para sa buong puno, pagkatapos paint. Ang paint phase ay maaaring laktawan kung hindi nagbago ang layout, na nakakatipid ng mga GPU resources.

Layout phase: mga hadlang at sukat

Sa panahon ng layout, ipinapadala ng Flutter ang mga hadlang (constraints) mula sa itaas pababa sa pamamagitan ng RenderObject Tree. Bawat magulang ay nagtatakda para sa child object ng minimum at maximum na lapad at taas. Kinakalkula ng child object ang sukat nito sa loob ng mga hadlang na ito at ibinabalik ito sa magulang. Ang prosesong ito ay tinatawag na "downward pass" (pagpapadala ng mga hadlang pababa) at "upward pass" (pagpapadala ng mga sukat pataas).

  • BoxConstraints — ang pinakakaraniwang uri ng hadlang: minWidth, maxWidth, minHeight, maxHeight.
  • SliverConstraints — ginagamit sa ScrollView para sa virtualization: sa standard na mga hadlang ay idinaragdag ang impormasyon tungkol sa pag-scroll.
  • RenderSliverMultiBoxAdaptor — namamahala ng layout ng mga virtualized na listahan, gumagawa ng RenderObject para lamang sa mga nakikitang elemento.

Paint phase: pagpapakita sa screen

Pagkatapos ng layout, isinasagawa ng Flutter ang paint — pagguhit ng bawat RenderObject. Gumagawa ang magulang ng PaintingContext, ipinapadala ito sa mga child object at tinutukoy ang offset. Bawat RenderObject ay gumuguhit ng sarili nito sa Canvas gamit ang mga graphic primitive: mga parihaba, bilog, teksto, larawan at pagbabago. Direktang nakikipag-ugnayan ang Canvas sa Skia o Impeller.

Pagmarka ng maruruming node

Gumagamit ang Flutter ng mekanismo ng "maruruming" node para mabawasan ang trabaho. Kapag sukat lamang ng isang RenderObject ang nagbago, hindi muling kinakalkula ng Flutter ang layout ng buong puno — minamarkahan nito ang binagong node at ang mga posibleng ninuno nito hanggang sa pinakamalapit na RenderBox na may nakapirming sukat. Gayundin, kapag nagbago ang anyo, tanging paint ang minamarkahan nang hindi inuulit ang layout.

Mga uri ng RenderObject sa Flutter

Nagbibigay ang Flutter ng ilang kategorya ng RenderObject para sa iba't ibang gawain: RenderBox para sa standard na mga parihabang elemento, RenderSliver para sa mga nai-scroll na lugar at custom na RenderObject para sa hindi standard na pag-render sa pamamagitan ng CustomPainter. Bawat uri ay na-optimize para sa papel nito sa puno ng pag-render.

RenderBox at mga sub-type nito

RenderBox — ang base na klase para sa mga parihabang elemento ng interface. Mga sub-type nito: RenderPadding (nagdaragdag ng espasyo), RenderTransform (naglalapat ng mga pagbabago), RenderFlex (nagpapatupad ng Row at Column), RenderStack (pagpatong ng mga elemento), RenderImage (pagpapakita ng mga larawan), RenderParagraph (pagpapakita ng teksto). Bawat sub-type ay nag-o-override ng performLayout at paint para sa sarili nitong lohika.

RenderSliver at virtualization

RenderSliver — ay isang uri ng RenderObject para sa pagtatrabaho sa mga nai-scroll na lugar. Hindi tulad ng RenderBox, ang Sliver ay gumagamit ng SliverConstraints na may kasamang impormasyon tungkol sa nakikitang lugar (viewport). Ang RenderSliverList at RenderSliverGrid ay gumagawa ng RenderObject para lamang sa mga elementong nasa nakikitang lugar, na nagpapahintulot sa pagproseso ng mga listahan na may milyon-milyong record.

Custom na RenderObject sa pamamagitan ng CustomPainter

Para sa hindi standard na graphics, gamitin ang CustomPaint at CustomPainter. Gumagawa ang CustomPaint ng RenderCustomPaint na tumatawag sa mga paint method sa CustomPainter. Pinapayagan nito ang pagguhit ng mga arbitraryong hugis, graph at animation na may buong kontrol sa Canvas. Ayon sa Flutter Team, ang CustomPainter ay mas mahusay kaysa sa nested standard widget para sa kumplikadong vector graphics.

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;
}

Sa halimbawang ito, ang CirclePainter ay gumuguhit ng bilog sa Canvas. Ang pamamaraang shouldRepaint ay nagbabalik ng true lamang kapag nagbago ang kulay, na pumipigil sa hindi kinakailangang pag-redraw. Ang CustomPainter ay dapat na kasinggaan hangga't maaari — gawin ang lahat ng mabibigat na kalkulasyon sa labas ng mga paint method.

RenderObject Tree ay ginagawa mula sa Element Tree sa pamamagitan ng mekanismo ng RenderObjectWidget. Bawat RenderObjectWidget (Padding, Transform, CustomPaint) ay gumagawa ng RenderObjectElement na gumagawa at namamahala ng kaukulang RenderObject. Ang elemento ay gumaganap bilang tagapamagitan: ipinapadala nito ang configuration mula sa widget patungo sa RenderObject at inaabisuhan ang RenderObject tungkol sa mga pagbabago.

Paggawa ng RenderObject mula sa elemento

Kapag na-mount ang RenderObjectElement, tinatawag nito ang pamamaraang createRenderObject ng widget nito. Gumagawa ang widget ng instance ng RenderObject at ibinabalik ito sa elemento. Inilalagay ng elemento ang RenderObject sa RenderObject Tree sa pamamagitan ng pagtawag sa pamamaraang insertChildLayout ng parent na RenderObject. Ang prosesong ito ay nangyayari lamang sa unang pag-mount — sa mga susunod na update, ina-update lamang ng elemento ang mga parameter ng umiiral na RenderObject.

Synchronization sa pamamagitan ng updateRenderObject

Kapag nagbago ang configuration ng widget (hal. nagbago ang value ng padding), tinatawag ng elemento ang pamamaraang updateRenderObject, na nagpapadala ng bagong configuration sa umiiral na RenderObject. Minamarkahan ng RenderObject ang sarili bilang "marumi" para sa layout o paint, at sa susunod na frame ay ginagawa ng framework ang mga kinakailangang update.

Pag-alis ng RenderObject

Sa pag-unmount ng elemento, tinatawag ang pamamaraang unmount, na nag-aalis ng RenderObject mula sa RenderObject Tree at nagpapalaya ng mga resources. Tinatawag ang RenderObject.remove para idiskonekta mula sa magulang, pagkatapos nito ang object ay maaaring kolektahin ng garbage collector. Ginagarantiyahan ng Flutter na ang RenderObject ay hindi nakabitin sa puno nang walang kaukulang elemento.

RepaintBoundary at paghihiwalay ng pag-render

RepaintBoundary — ay isang widget na gumagawa ng hiwalay na layer para sa pag-render ng nilalaman nito. Kapag nagbago ang nilalaman ng RepaintBoundary, itong layer lamang ang na-redraw at ang ibang bahagi ng screen ay nananatiling hindi nagbabago. Ang RepaintBoundary ay lalong kapaki-pakinabang para sa mga animation, video player, interactive graph at iba pang madalas na ina-update na elemento.

Paano gumagana ang RepaintBoundary

Sa puso ng RepaintBoundary ay ang RenderRepaintBoundary — isang espesyal na RenderObject na gumagawa ng hiwalay na PictureLayer. Sa unang pag-render, itinatala ng RenderRepaintBoundary ang mga graphic command sa layer na ito. Sa mga susunod na update, kung tanging ang nilalaman sa loob ng RepaintBoundary ang nagbago, iredraw lamang ng Flutter ang layer na ito, hindi ang buong screen. Ang ibang mga layer ay nananatiling hindi nagbabago at ginagamit muli.

Kailan gagamitin ang RepaintBoundary

Hindi lahat ng widget ay nangangailangan ng RepaintBoundary. Gamitin ito kapag ang bahagi ng interface ay ina-update nang may mataas na dalas (60 FPS at pataas), habang ang natitirang screen ay static. Mga tipikal na halimbawa: animated na loading indicator, video player, game Canvas, CustomPainter na may madalas na pag-redraw. Para sa static na teksto o mga button, ang RepaintBoundary ay kalabisan at nagpapataas lamang ng pagkonsumo ng memorya.

ScenarioRekomendasyonDahilan
AnimationBalutin sa RepaintBoundaryInihihiwalay ang madalas na ina-update na lugar
Listahang nai-scrollHindi kailanganAwtomatikong gumagamit ng layer ang ListView
Static na tekstoHindi kailanganWalang madalas na pag-redraw
CustomPainterInirerekomendaMadalas na pag-redraw ng graphics

Pag-optimize ng RenderObject Tree para sa performance

Performance ng RenderObject Tree ay depende sa bilang ng mga node, lalim ng puno at dalas ng pag-redraw. Ang mga tool ng Flutter DevTools (tab na "Rendering") ay nagpapahintulot ng real-time na pagsusuri ng RenderObject Tree: bilang ng repaint, oras ng layout at paint, bilang ng mga layer at kanilang sukat. Ang regular na pagsusuri ay tumutulong na matukoy ang mga bottleneck.

Iwasan ang labis na overdraw

Overdraw — ay isang sitwasyon kung saan ang isang pixel ay iginuhit nang maraming beses bawat frame. Halimbawa, kapag ang isang semi-transparent na widget ay inilagay sa ibabaw ng isa pa, iginuguhit ng GPU ang parehong layer. Gumamit ng opaque flags (Container na may color sa halip na decoration) para sa mga opaque na elemento upang laktawan ng Flutter ang mga hindi nakikitang layer. Ayon sa Flutter Team, ang pagbawas ng overdraw ay maaaring paikliin ang oras ng paint ng hanggang 30%.

Minimumin ang bilang ng mga layer

Bawat RepaintBoundary at ilang widget (Opacity, ClipRRect, Transform) ay gumagawa ng hiwalay na layer (PictureLayer). Masyadong maraming layer ay nagpapataas ng oras ng komposisyon. Gumamit ng pagpapangkat: sa halip na maraming Opacity sa magkahiwalay na widget, mag-apply ng isang Opacity sa isang container. Sa halip na ClipRRect sa bawat elemento, gumamit ng ClipRRect sa isang karaniwang container.

Gumamit ng const-constructor

Kapag ang isang widget ay idineklara bilang const, alam ng Flutter na hindi magbabago ang configuration nito at maaaring muling gamitin ang kaukulang RenderObject nang hindi muling ginagawa. Ang mga const-constructor ay nagbabawas ng karga sa garbage collector at nagpapabilis ng unang frame. Gumamit ng const para sa mga widget na may nakapirming parameter: mga icon, heading, dekoratibong elemento.

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

Mga madalas itanong

Paano naiiba ang RenderObject Tree sa Widget Tree?

Widget Tree — ay isang magaan na configuration ng interface na muling ginagawa sa bawat rebuild. RenderObject Tree — ay isang mabigat na puno ng mga object ng pag-render na pinapanatili at ina-update lamang kapag nagbago ang geometry o anyo.

Paano makita ang RenderObject Tree sa debugger?

Gamitin ang Flutter DevTools — tab na "Rendering". Makikita mo ang mga layer ng pag-render, oras ng layout at paint, pati na rin ang detalyadong impormasyon tungkol sa bawat RenderObject: sukat, constraints, flag ng pangangailangan ng update.

Ano ang dirty RenderObject?

Dirty — ay isang RenderObject na minarkahan bilang nangangailangan ng update. Ang flag na _needsLayout o _needsPaint ay itinatakda kapag nagbago ang configuration, at isasagawa ng Flutter ang layout o paint para sa node na ito sa susunod na frame.

Maaari ba akong gumawa ng sarili kong RenderObject?

Oo, gumawa ng subclass ng RenderBox at i-override ang mga pamamaraang performLayout at paint. Gumamit ng RenderObjectWidget para i-embed ang custom na RenderObject sa Widget Tree. Ito ay isang advanced na pamamaraan para sa hindi standard na pag-render.

Paano naaapektuhan ng RepaintBoundary ang RenderObject Tree?

RepaintBoundary ay gumagawa ng RenderRepaintBoundary na naghihiwalay ng bahagi ng RenderObject Tree sa isang hiwalay na layer. Kapag nagbago ang nilalaman, ang layer na ito lamang ang na-redraw at ang natitirang puno ay nananatiling hindi nagbabago.

Buod

  • RenderObject Tree — ikatlong antas ng arkitektura ng Flutter, responsable para sa layout at paint ng bawat elemento ng interface.
  • Bawat RenderObject ay nagsasagawa ng dalawang phase: layout (pagkalkula ng mga sukat at posisyon) at paint (pagguhit ng mga pixel sa pamamagitan ng Canvas).
  • RenderBox — base na uri para sa standard na mga elemento, RenderSliver — para sa virtualization ng mga nai-scroll na listahan.
  • RenderObject Tree ay naka-sync sa Element Tree sa pamamagitan ng RenderObjectElement na gumagawa at nag-a-update ng RenderObject.
  • RepaintBoundary ay naghihiwalay ng bahagi ng puno sa isang hiwalay na layer, na pumipigil sa buong pag-redraw ng screen sa mga lokal na pagbabago.
  • Performance ay depende sa lalim ng puno, bilang ng mga layer, overdraw at paggamit ng const-constructor.
  • Flutter DevTools ay nagbibigay ng mga tool para sa pagsusuri ng RenderObject Tree: oras ng layout, oras ng paint, bilang ng mga layer at repaint.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din