Isolates & compute
jank ที่ await ออกไปไม่ได้
หัวข้อที่มีชื่อว่า “jank ที่ await ออกไปไม่ได้”async/await แก้เรื่องการรอ (network, disk) — แต่ ไม่ ช่วยเรื่องงาน CPU หนัก การ parse JSON 5MB, resize รูป, หรือรัน crypto hash เป็นการคำนวณแบบ synchronous และรันบน UI isolate ระหว่างที่รัน event loop render frame ไม่ได้ แอปจึงค้าง
คุณ await ออกจากปัญหานี้ไม่ได้ เพราะไม่มีอะไรให้ รอ — CPU กำลังยุ่ง ทางแก้คือย้ายงานไป isolate อื่น เพื่อให้ UI isolate ว่างพอจะ render
compute(): กรณีทั่วไป
หัวข้อที่มีชื่อว่า “compute(): กรณีทั่วไป”สำหรับ “รัน expensive pure function นี้นอก main isolate” แบบทั่วไป Flutter ให้ compute() ส่ง top-level (หรือ static) function กับ argument ของตัวเอง จะสร้าง background isolate ขึ้นมา รัน function ที่นั่น แล้วคืนผลเป็น Future
// top-level function — จำเป็น เพราะต้องรันบน isolate อื่นList<Item> parseItems(String jsonStr) { final raw = jsonDecode(jsonStr) as List; return raw.map((e) => Item.fromJson(e)).toList(); // งานหนัก}
// บน UI isolate — offload มัน แล้ว await ผลโดยไม่ jank:final items = await compute(parseItems, hugeJsonString);UI ยัง render ที่ 60fps ระหว่างที่ parse รันอยู่ที่อื่น compute เป็นเครื่องมือที่ถูก ~90% ของกรณี
raw isolate และ port
หัวข้อที่มีชื่อว่า “raw isolate และ port”สำหรับ worker ที่อยู่ยาวหรือการสื่อสารสองทาง ใช้ Isolate.spawn กับ port — isolate ไม่แชร์ memory จึงคุยกันด้วยการส่ง message ผ่าน SendPort/ReceivePort
flowchart LR main["UI isolate (render ต่อเนื่อง)"] -->|ส่ง message| worker["Worker isolate (ทำงาน CPU)"] worker -->|ส่งผลกลับ| main note["ไม่แชร์ memory: ข้ามได้แค่ message ที่ถูก copy"] --- worker
boundary: ไม่แชร์ memory
หัวข้อที่มีชื่อว่า “boundary: ไม่แชร์ memory”กฎที่กำหนดทุกอย่าง: isolate ไม่แชร์ memory อะไรที่คุณส่งจะถูก copy ข้าม boundary (มี fast-path ยกเว้นบ้างเช่น TransferableTypedData) ผลที่ตามมา:
- คุณส่ง closure ที่ capture UI state หรือ object graph ที่คุณ mutate อยู่ไม่ได้
- ส่งข้อมูลใหญ่มากมีต้นทุนการ copy — บางครั้งการ copy กินส่วนที่ประหยัดไปหมด
- worker function ต้อง self-contained (top-level/static) รับ plain data เข้าและคืน plain data ออก
นี่คือ message-passing model เดียวกับในบทเรียน Dart async แต่ตอนนี้ใช้เพื่อ parallelism แทน concurrency