RenderObject Tree হল Flutter পদানুক্রমের তৃতীয় স্তর, যা স্ক্রিনে ইন্টারফেসের প্রকৃত রেন্ডারিংয়ের জন্য দায়ী। এই ট্রির প্রতিটি নোড আকার গণনা (layout) এবং অংকন (painting) করে, যা উইজেট কনফিগারেশনকে পিক্সেলে রূপান্তর করে। Widget Tree এর বিপরীতে, RenderObject Tree একবার তৈরি হয় এবং শুধুমাত্র জ্যামিতি বা চেহারা পরিবর্তন হলে আপডেট হয়। অনুযায়ী Flutter API Reference, 2025, RenderObject Tree এর কর্মদক্ষতা সরাসরি অ্যানিমেশনের মাত্রুতা এবং অ্যাপ্লিকেশনের প্রতিক্রিয়াশীলতা নির্ধারণ করে।
মূখ্য বিষয়
RenderObject Tree হল রেন্ডার অবজেক্টের একটি পদানুক্রমিত গঠন যা মেমোরিতে ইন্টারফেসের প্রকৃত প্রতিনিধিত্ব হিসেবে কাজ করে। প্রতিটি RenderObject নিজের আকার, স্ক্রিনে অবস্থান এবং কিভাবে নিজেকে আকাতে হয় তা জানে। উইজেটের বিপরীতে, যা হালকা এবং প্রতি সেকেন্ড শত বার পুনর্নির্মাণ করা যেতে পারে, RenderObject হল একটি ভারী অবজেক্ট যার গ্রাফিক্স পাইপলাইনে সরাসরি প্রবেশাধিকার রয়েছে।
উইজেট থেকে পিক্সেলে যাওয়ার পথ তিনটি পর্যায়ে সম্পন্ন হয়: Widget Tree বলে স্ক্রিনে কী থাকা উচিত; Element Tree জীবন চক্র পরিচালনা করে; RenderObject Tree প্রকৃত কাজ করে। প্রতিটি RenderObjectWidget (যেমন Padding, Transform, CustomPaint) একটি RenderObject তৈরি করে যা রেন্ডার ট্রিতে যুক্ত হয়। RenderBox হল সবচেয়ে সাধারণ ধরনের RenderObject, যা 99% মানক উইজেটে ব্যবহৃত হয়।
RenderObject হল একটি অ্যাবস্ট্রাক্ট ক্লাস যা layout এবং paint এর জন্য ইন্টারফেস সংজ্ঞায়িত করে। এতে পিতৃ RenderObject এবং শিশু অবজেক্টের রেফারেন্স এবং অ্যাবস্ট্রাক্ট পদ্ধতি রয়েছে: performLayout, paint এবং hitTest। প্রতিটি কনক্রিট RenderObject নিজের আচরণ অনুযায়ী এই পদ্ধতিগুলি বাস্তবায়ন করে: RenderFlex শিশুদের মধ্যে স্থান বণ্টন করে, RenderImage ছবি প্রদর্শন করে, RenderParagraph টেক্সট উপস্থাপন করে।
abstract class RenderObject {
RenderObject? parent;
Constraints constraints;
ParentData? parentData;
bool _needsLayout = true;
bool _needsPaint = true;
void performLayout();
void paint(PaintingContext context, Offset offset);
}
এই সরল কাঠামোতে, RenderObject এ _needsLayout এবং _needsPaint ফ্ল্যাগ রয়েছে, যা অবজেক্টকে আপডেটের প্রয়োজন হিসেবে চিহ্নিত করে। যখন Widget Tree পরিবর্তিত হয়, Element Tree সংশ্লিষ্ট RenderObjects কে layout বা paint এর জন্য "মলিন" হিসেবে চিহ্নিত করে, এবং পরবর্তী ফ্রেমে Flutter কেবল প্রয়োজনীয় কাজগুলিই করে।
প্রতিটি RenderObject দুটি মূল পর্যায় সম্পাদন করে: layout (আকার এবং অবস্থান নির্ধারণ) এবং paint (অংকন)। এই পর্যায়গুলি কঠোর ক্রমে সম্পাদিত হয়: প্রথমে সম্পূর্ণ ট্রির জন্য layout, তারপর paint। যদি layout পরিবর্তিত না হয় তবে paint পর্যায়টি এড়িয়ে দেওয়া যেতে পারে, যা GPU সম্পদ সংরক্ষ করে।
layout এর সময়, Flutter RenderObject Tree এর মাধ্যমে উপর থেকে নীচে সীমাবদ্ধতা (constraints) প্রেরণ করে। প্রতিটি পিতৃ নিজের শিশুর জন্য সর্বনিম্ন এবং সর্বোচ্চ প্রস্থ এবং দৈর্ঘ্য নির্ধারণ করে। শিশু এই সীমাবদ্ধতার মধ্যে নিজের আকার নির্ধারণ করে এবং পিতৃর কাছে ফিরিয়ে দেয়। এই প্রক্রিয়াকে "ডাউনওয়ার্ড পাস" (সীমাবদ্ধতা নীচে পার্শ করা) এবং "আপওয়ার্ড পাস" (আকার উপরে পার্শ করা) বলা হয়।
layout সম্পূর্ণ হলে, Flutter paint করে — প্রতিটি RenderObject অংকন করে। পিতৃ PaintingContext তৈরি করে, এটি শিশু অবজেক্টে প্রেরণ করে এবং অফসেট (offset) নির্দিষ্ট করে। প্রতিটি RenderObject গ্রাফিক্স প্রিমিটিভ ব্যবহার করে Canvas এ নিজেকে আকাে: আয়ত, বৃত্ত, টেক্সট, ছবি এবং ট্রান্সফর্মেশন। Canvas সরাসরি Skia বা Impeller এর সাথে যোগাযোগ করে।
Flutter কাজ কমাতে "মলিন" নোড প্রক্রিয়া ব্যবহার করে। যখন কেবল একটি RenderObject এর আকার পরিবর্তিত হয়, Flutter সম্পূর্ণ ট্রির layout পুনর্গণনা করে না — এটি পরিবর্তিত নোড এবং এর সম্ভাব্য পূর্বরজগুলিকে নির্দিষ্ট আকারের নিকটতম RenderBox পর্যন্ত চিহ্নিত করে। অনুরূপভাবে, যখন চেহারা পরিবর্তিত হয়, layout পুনরায় না করে কেবল paint চিহ্নিত করা হয়।
Flutter বিভিন্ন কাজের জন্য RenderObject এর বেশ কয়েকটি বিভাগ প্রদান করে: মানক আয়তাকার উপাদানের জন্য RenderBox, স্ক্রলযোগ্য অঞ্চলের জন্য RenderSliver, এবং CustomPainter এর মাধ্যমে अমানক রেন্ডারিংয়ের জন্য কস্টম RenderObjects। প্রতিটি ধরন রেন্ডার ট্রিতে নিজের ভূমিকার জন্য অপ্টিমইজড ।
RenderBox আয়তাকার ইন্টারফেস উপাদানের জন্য মৌলিক ক্লাস। এর উপপ্রকারগুলির মধ্যে রয়েছে: RenderPadding (প্যাডিং যোগ করে), RenderTransform (ট্রান্সফর্মেশন প্রয়োগ করে), RenderFlex (Row এবং Column বাস্তবায়ন করে), RenderStack (উপাদান স্ট্যাক করে), RenderImage (ছবি প্রদর্শন করে), RenderParagraph (টেক্সট উপস্থাপন করে)। প্রতিটি উপপ্রকার নিজের যুক্তির জন্য performLayout এবং paint অনুসরণ করে।
RenderSliver হল স্ক্রলযোগ্য অঞ্চলের সাথে কাজ করার জন্য এক ধরনের RenderObject। RenderBox এর বিপরীতে, Sliver SliverConstraints ব্যবহার করে, যার মধ্যে ভিউপোর্ট তথ্য অন্তর্ভুক্ত থাকে। RenderSliverList এবং RenderSliverGrid কেবল দৃশ্যমান অঞ্চলের আইটেমের জন্য RenderObjects তৈরি করে, যা লাখ এন্ট্রি থাকা তালিকা পরিচালনার অনুমতি দেয়।
অমানক গ্রাফিক্সের জন্য, CustomPaint এবং CustomPainter ব্যবহার করুন। CustomPaint RenderCustomPaint তৈরি করে, যা CustomPainter এর paint পদ্ধতি কল করে। এটি Canvas এর উপর সম্পূর্ণ নিয়ন্ত্রণ সহ ইচ্ছামতো আকৃতি, গ্রাফ এবং অ্যানিমেশন আকার করার অনুমতি দেয়। Flutter টিমের মতে, জটিল ভেক্টর গ্রাফিক্সের জন্য CustomPainter নেস্টেড মানক উইজেটের চেয়ে অধিক দক্ষ।
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;
}
এই উদাহরণে, CirclePainter Canvas এ একটি বৃত্ত আকাে। shouldRepaint পদ্ধতি কেবল রঙ পরিবর্তন হলেই true রিটার্ন করে, যা অনাবশ্যক পুনরায রেন্ডারিং প্রতিরোধ করে। CustomPainter যতটা সম্ভব হালকা হতে হবে — সম্পূর্ণ ভারী গণনা paint পদ্ধতির বাইরে সম্পাদন করুন।
RenderObject Tree RenderObjectWidget প্রক্রিয়ার মাধ্যমে Element Tree থেকে তৈরি হয়। প্রতিটি RenderObjectWidget (Padding, Transform, CustomPaint) একটি RenderObjectElement তৈরি করে, যা পরিবর্তে সংশ্লিষ্ট RenderObject তৈরি এবং পরিচালনা করে। উপাদানটি একটি মধ্যস্থের ভূমিকা পালন করে: এটি উইজেট থেকে RenderObject এ কনফিগারেশন প্রেরণ করে এবং RenderObject কে পরিবর্তন সম্পর্কে অবহিত করে।
যখন RenderObjectElement মাউন্ট হয়, এটি নিজের উইজেটে createRenderObject পদ্ধতি কল করে। উইজেটটি একটি RenderObject ইনস্টেন্স তৈরি করে এবং উপাদানকে ফিরিয়ে দেয়। উপাদানটি পিতৃ RenderObject এর insertChildLayout পদ্ধতি কল করে RenderObject কে RenderObject Tree এ সন্নিবেশ করে। এই প্রক্রিয়া কেবল প্রথম মাউন্টে সংঘটিত হয় — পরবর্তী আপডেটে, উপাদানটি বর্তমান RenderObject এর প্যারামিটার আপডেট করে।
যখন উইজেটের কনফিগারেশন পরিবর্তিত হয় (যেমন, প্যাডিং মান পরিবর্তন হয়), উপাদানটি updateRenderObject পদ্ধতি কল করে, যা বর্তমান RenderObject এ নতুন কনফিগারেশন প্রেরণ করে। RenderObject নিজেকে layout বা paint এর জন্য "মলিন" চিহ্নিত করে, এবং পরবর্তী ফ্রেমে ফ্রেমওয়ার্ক প্রয়োজনীয় আপডেট করে।
যখন একটি উপাদান আনমাউন্ট করা হয়, unmount পদ্ধতি কল করা হয়, যা RenderObject কে RenderObject Tree থেকে সরায় এবং সম্পদ মুক্ত করে। পিতৃ থেকে বিয়োজনের জন্য RenderObject.remove কল করা হয়, যার পরে অবজেক্টটি গার্বেজ কলেক্ট করা যেতে পারে। Flutter গারন্টি দেয় যে কোনো RenderObject সংশ্লিষ্ট উপাদান ছাড়া ট্রিতে ঝুলে থাকে না।
RepaintBoundary হল একটি উইজেট যা নিজের বস্তু রেন্ডার করার জন্য একটি পৃথক স্তর তৈরি করে। যখন RepaintBoundary এর ভিতরের বস্তু পরিবর্তিত হয়, কেবল সেই স্তরটি পুনরায় রেন্ডার হয়, এবং বাকি স্ক্রিন অপরিবর্তিত থাকে। RepaintBoundary অ্যানিমেশন, ভিডিও প্লেয়ার, ইন্টার্যাক্টিভ চার্ট এবং অন্য বারবার আপডেটহোয়া উপাদানের জন্য বিশেষ ভাবে উপযোগী।
RepaintBoundary এর মূলে RenderRepaintBoundary রয়েছে — একটি বিশেষ RenderObject যা একটি পৃথক PictureLayer তࣈরি করে। প্রথম রেন্ডারে, RenderRepaintBoundary এই স্তরে গ্রাফিক্স কমান্ড রিকর্ড করে। পরবর্তী আপডেটে, যদি RepaintBoundary এর ভিতরের বস্তু মাত্র পরিবর্তিত হয়, Flutter সম্পূর্ণ স্ক্রিনের পরিবর্তে কেবল এই স্তরটি পুনরায় রেন্ডার করে। অন্য স্তরগুলি অপরিবর্তিত থাকে এবং পুনরায় ব্যবহৃত হয়।
প্রতিটি উইজেটের RepaintBoundary প্রয়়োজন হয় না। এটি ব্যবহার করুন যখন ইন্টারফেসের এক অংশ উচ্চ ফ্রিকুয়েন্সিতে (60 FPS বা তার চেয়ে অধিক) আপডেট হয় এবং বাকি স্ক্রিন স্থির থাকে। নমূনা উদাহরণ: একটি অ্যানিমেটেড লোডিং ইন্ডিকেটর, ভিডিও প্লেয়ার, গেম Canvas, বারবার পুনরায় রেন্ডার করা CustomPainter। স্থির টেক্সট বা বতনের জন্য, RepaintBoundary অতিরিক্ত এবং কেবল মেমোরি ব্যবহার বাড়ায়।
| দৃশ্য | সুপারিশ | কারণ |
|---|---|---|
| অ্যানিমেশন | RepaintBoundary এ মুড়িয়ে দিন | বারবার আপডেটহোয়া অঞ্চলকে পৃথক করে |
| স্ক্রলযোগ্য তালিকা | প্রয়়োজন নেই | ListView স্বয়ংক্রিয়ভাবে স্তর ব্যবহার করে |
| স্থির টেক্সট | প্রয়়োজন নেই | বারবার পুনরায় রেন্ডারিং হয় না |
| CustomPainter | সুপারিশ করা হয় | বারবার গ্রাফিক্স পুনরায় রেন্ডারিং |
কর্মদক্ষতা RenderObject Tree এর নোডের সংখ্যা, ট্রির গভীরতা এবং পুনরায় রেন্ডারিং ফ্রিকুয়েন্সির উপর নির্ভর করে। Flutter DevTools ("Rendering" ট্যাব) আপনাকে বাস্তব সময়ে RenderObject Tree বিশ্লেষণ করার অনুমতি দেয়: পুনরায় রেন্ডার গণনা, layout এবং paint সময়, স্তরের সংখ্যা এবং তাদের আকার। নিয়মিত বিশ্লেষণ বাধা চিহ্নিত করতে সাহায্য করে।
Overdraw হল একটি পরিস্থিতি যেখানে একটি পিক্সেল প্রতি ফ্রেম একাধিক বার আকা হয়। উদাহরণস্বরূপ, যখন একটি আর্ধ-স্বচ্ছ উইজেট অন্যটির উপর আবরণ করে, GPU উভয় স্তর আকে। অপ্রসারে উপাদানের এজন্য অপ্যাক ফ্ল্যাগ ব্যবহার করুন (decoration এর পরিবর্তে color সহ Container) যাতে Flutter অদৃশ্য স্তর এড়িয়ে যেতে পারে। Flutter টিমের মতে, overdraw কমালে paint সময় 30% পর্যন্ত কমতে পারে।
প্রতিটি RepaintBoundary এবং কিছু উইজেট (Opacity, ClipRRect, Transform) একটি পৃথক স্তর (PictureLayer) তࣈরি করে। অনেক স্তর কম্পোজিশন সময় বাড়ায়। গ্রুপিং ব্যবহার করুন: পৃথক উপাদানে একাধিক Opacity উইজেটের পরিবর্তে, কন্টেনারে একটি Opacity প্রয়োগ করুন। প্রতিটি উপাদানে ClipRRect এর পরিবর্তে, সাধারণ কন্টেনারে ClipRRect ব্যবহার করুন।
যখন একটি উইজেটকে const ঘোষণা করা হয়, Flutter জানে যে এর কনফিগারেশন পরিবর্তন হবে না এবং সংশ্লিষ্ট RenderObject কে পুনরায় সৃষ্টি ছাড়া পুনরায় ব্যবহার করতে পারে। const কন্স্ট্রাক্টার গার্বেজ কলেক্শন লোড কমায় এবং প্রথম ফ্রেম দ্রুত করে। নির্দিষ্ট প্যারামিটার বিশিষ্ট উইজেটের জন্য const ব্যবহার করুন: আইকন, শিরোনাম, সাজানো উপাদান।
const Text("শিরোনাম", style: TextStyle(fontSize: 24));
const Icon(Icons.home, color: Colors.blue);
const SizedBox.shrink();
প্রায়ই জিজ্ঞাসিত প্রশ্ন
Widget Tree হল একটি হালকা ইন্টারফেস কনফিগারেশন যা প্রতিটি পুনর্নির্মাণে পুনরায় সৃষ্টি করা হয়। RenderObject Tree হল রেন্ডার অবজেক্টের একটি ভারী ট্রি যা টিকে থাকে এবং কেবল জ্যামিতি বা চেহারা পরিবর্তন হলেই আপডেট হয়।
Flutter DevTools ব্যবহার করুন — "Rendering" ট্যাব। আপনি রেন্ডার স্তর, layout এবং paint সময়, এবং প্রতিটি RenderObject এর বিস্তারিত তথ্য দেখতে পাবেন: আকার, সীমাবদ্ধতা এবং ডার্টি ফ্ল্যাগ।
Dirty হল একটি RenderObject যা আপডেটের প্রয়োজন হিসেবে চিহ্নিত। কনফিগারেশন পরিবর্তনে _needsLayout বা _needsPaint ফ্ল্যাগ সেট হয়, এবং Flutter পরবর্তী ফ্রেমে সেই নোডের জন্য layout বা paint করে।
হ্যাঁ, RenderBox এর একটি উপবর্গ তৈরি করুন এবং performLayout এবং paint পদ্ধতি অনুসরণ করুন। কস্টম RenderObject কে Widget Tree এ এম্বেড করার জন্য RenderObjectWidget ব্যবহার করুন। এটি অমানক রেন্ডারিংয়ের জন্য একটি উন্নত কৌশল।
RepaintBoundary RenderRepaintBoundary তࣈরি করে, যা RenderObject Tree এর এক অংশকে একটি পৃথক স্তরে পৃথক করে। যখন বস্তু পরিবর্তিত হয়, কেবল সেই স্তরটি পুনরায় রেন্ডার হয়, এবং বাকি ট্রি অপরিবর্তিত থাকে।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন