Rebuilds & Performance
Rebuild ถูก — จนกว่าจะไม่ถูก
หัวข้อที่มีชื่อว่า “Rebuild ถูก — จนกว่าจะไม่ถูก”การ rebuild widget subtree มักจะเร็ว: Flutter diff widget ใหม่กับ element แล้ว update เฉพาะที่เปลี่ยน ปัญหาคือ rebuild มากเกินจำเป็น — rebuild subtree ใหญ่ทั้งที่ชิ้นเล็กชิ้นเดียวเปลี่ยน ทุก frame ของ animation lever ด้านล่างล้วนลดงาน rebuild และ repaint ที่สูญเปล่า
Lever 1: const constructor
หัวข้อที่มีชื่อว่า “Lever 1: const constructor”const widget ถูกสร้างตอน compile time และถูก canonicalize เมื่อ parent rebuild Flutter เห็น instance const ตัวเดิม แล้ว ข้ามการ rebuild subtree นั้นทั้งก้อน
// subtree นี้เป็น const — build ครั้งเดียวและถูกข้ามทุก parent rebuildconst Padding( padding: EdgeInsets.all(16), child: Text('Static label'),)การใส่ const ทุกที่ที่ input ของ widget เป็น compile-time constant ทั้งหมด คือ performance win ที่ถูกที่สุดใน Flutter เปิด lint prefer_const_constructors แล้วทำตามที่ lint บอก
Lever 2: narrow scope ของ setState
หัวข้อที่มีชื่อว่า “Lever 2: narrow scope ของ setState”setState rebuild output ของ build ทั้งหมด ของ State นั้น ถ้าหน้าจอยักษ์เรียก setState เพื่อ counter เล็ก ๆ ทั้งหน้าจอก็ rebuild
// ❌ setState ตรงนี้ rebuild ทั้งหน้าจอเพื่อเลขตัวเดียว// ✅ ดึงส่วนที่เปลี่ยนออกไปเป็น StatefulWidget เล็ก ๆ ของตัวเอง// ให้เฉพาะ widget นั้น rebuild ส่วนที่เหลือคง const ไว้Pattern คือ: ดัน state ลงล่าง ไปที่ widget เล็กที่สุดที่ต้องใช้ และคง widget รอบ ๆ ให้เป็น const เพื่อให้อยู่นิ่ง
Lever 3: subtree ที่นิ่ง และ RepaintBoundary
หัวข้อที่มีชื่อว่า “Lever 3: subtree ที่นิ่ง และ RepaintBoundary”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 บ่อยไว้ในนั้นเพื่อจำกัดความเสียหาย
Lever 4: วัดด้วย DevTools
หัวข้อที่มีชื่อว่า “Lever 4: วัดด้วย DevTools”อย่าเดา Flutter DevTools แสดง rebuild count (widget ไหน rebuild บ่อยแค่ไหน), timeline ของ frame time (หา frame ที่เกิน budget) และ widget inspector workflow คือ: ทำ jank ให้เกิดซ้ำ, เปิด timeline, หา frame ที่แพง, แล้วดูว่า subtree ไหนทำงานมากเกินไป