ข้ามไปยังเนื้อหา

Rebuilds & Performance

การ rebuild widget subtree มักจะเร็ว: Flutter diff widget ใหม่กับ element แล้ว update เฉพาะที่เปลี่ยน ปัญหาคือ rebuild มากเกินจำเป็น — rebuild subtree ใหญ่ทั้งที่ชิ้นเล็กชิ้นเดียวเปลี่ยน ทุก frame ของ animation lever ด้านล่างล้วนลดงาน rebuild และ repaint ที่สูญเปล่า

const widget ถูกสร้างตอน compile time และถูก canonicalize เมื่อ parent rebuild Flutter เห็น instance const ตัวเดิม แล้ว ข้ามการ rebuild subtree นั้นทั้งก้อน

// subtree นี้เป็น const — build ครั้งเดียวและถูกข้ามทุก parent rebuild
const Padding(
padding: EdgeInsets.all(16),
child: Text('Static label'),
)

การใส่ const ทุกที่ที่ input ของ widget เป็น compile-time constant ทั้งหมด คือ performance win ที่ถูกที่สุดใน Flutter เปิด lint prefer_const_constructors แล้วทำตามที่ lint บอก

setState rebuild output ของ build ทั้งหมด ของ State นั้น ถ้าหน้าจอยักษ์เรียก setState เพื่อ counter เล็ก ๆ ทั้งหน้าจอก็ rebuild

// ❌ setState ตรงนี้ rebuild ทั้งหน้าจอเพื่อเลขตัวเดียว
// ✅ ดึงส่วนที่เปลี่ยนออกไปเป็น StatefulWidget เล็ก ๆ ของตัวเอง
// ให้เฉพาะ widget นั้น rebuild ส่วนที่เหลือคง const ไว้

Pattern คือ: ดัน state ลงล่าง ไปที่ widget เล็กที่สุดที่ต้องใช้ และคง widget รอบ ๆ ให้เป็น const เพื่อให้อยู่นิ่ง

flowchart TB
  screen["หน้าจอใหญ่ (const, นิ่ง)"] --> counter["widget เล็กที่เปลี่ยน
(State ของตัวเอง)"]
  screen --> rest["const siblings
ไม่ rebuild ไม่ repaint"]
  counter --> rb["ห่อส่วนหนัก/animated
ด้วย RepaintBoundary"]
แยกส่วนที่เปลี่ยนออกมาทำให้ที่เหลือนิ่ง

RepaintBoundary ให้ subtree มี paint layer ของตัวเอง การ repaint จึงไม่ลากเพื่อนบ้าน repaint ตามไปด้วย ห่อ animation หรือ widget ที่ update บ่อยไว้ในนั้นเพื่อจำกัดความเสียหาย

อย่าเดา Flutter DevTools แสดง rebuild count (widget ไหน rebuild บ่อยแค่ไหน), timeline ของ frame time (หา frame ที่เกิน budget) และ widget inspector workflow คือ: ทำ jank ให้เกิดซ้ำ, เปิด timeline, หา frame ที่แพง, แล้วดูว่า subtree ไหนทำงานมากเกินไป

ทำไม const widget ช่วยเรื่อง performance?
ผลของการเรียก setState ใน State class ใหญ่คืออะไร?
RepaintBoundary ทำอะไร?
ควรหาปัญหา performance อย่างไร?