Flutter: Hot Reload vs Hot Restart vs Full Restart

Published on

Authored by Pete. Pittawat Taveekitworachai.


หนึ่งในข้อได้เปรียบของการพัฒนา Mobile Application บน Flutter คือ Hot Reload ที่ช่วยให้การพัฒนา UI ในโลกของ Mobile Application Development เป็นไปได้ด้วยดียิ่งขึ้น เพราะเราะสามารถเหตุผลลัพธ์ได้(เกือบจะ)ทันทีที่มีการบันทึกไฟล์โค้ดของเรา ซึ่งเป็นผลมาจากทีมที่พัฒนา Flutter นั้น แต่เดิมเป็นทีมที่พัฒนาเกี่ยวกับเว็บซึ่งมีการแสดงผลอย่างทันทีที่มีการบันทึกไฟล์ และต้องการจะนำประสบการณ์แบบเดียวกันมาสู่การพัฒนาแอปพลิเคชันบนอุปกรณ์เคลื่อนที่นั่นเอง

อย่างไรก็ตามเนื่องจากวิธีการที่ Flutter ใช้ในการทำ Hot Reload หลาย ๆ ครั้งที่เราไม่เข้าใจหลักการทำงานของมันทำให้เกิดบัคซึ่งเป็นผลมาจากการ Hot Reload โดยไม่ได้ตั้งใจ และไม่เกี่ยวกับการที่เราทำให้เกิดบัคในโปรแกรมของเราเอง บทความนี้จึงอยากชวนทุกคนมาทำความเข้าใจกันว่า Hot Reload, Hot Restart และ Full Restart ต่างกันอย่างไร ซึ่งจะช่วยให้ทุก ๆ คนไม่ตกใจเวลาเจอ Error แม้ว่าเราจะมั่นใจว่าเขียนโค้ดได้ถูกต้องนั่นเอง


Hot Reload

Hot Reload เป็นสิ่งที่เรามักจะใช้บ่อยที่สุด โดยเป็นการ Inject code ส่วนที่เปลี่ยนแปลงให้กับ VM และ Rebuild Widget Tree ขึ้นมาใหม่ จึงทำให้การ Hot Reload นั้นใช้เวลาน้อยที่สุดเมื่อเทียบกับสองวิธีที่เหลือ

จุดสำคัญของ Hot Reload คือ มันไม่ได้เคลียร์ State ของแอพ ซึ่งเป็นทั้งข้อดีและข้อเสียในเวลาเดียวกัน ข้อดีคือเราสามารถทดสอบ UI ที่ผูกกับ State ที่จำเพาะเจาะจงได้ง่ายยิ่งขึ้น หรือในกรณีที่เรามีการ Navigate ไปในแอพที่ความลึกระดับหนึ่งก็จะยังคงอยู่ที่ระดับเดิม ไม่ได้ถูกพากลับไปใหม่ตั้งแต่ต้น

ส่วนข้อเสียก็คือบางครั้งเรามีการเปลี่ยนแปลง Business Logic ที่ทำให้ State ปัจจุบันไม่มีทางเกิดขึ้นมาได้

นอกจากนี้ Hot Reload ยังทำงานได้ไม่ถูกต้องหาก Widget มีการเปลี่ยนประเภท คือ จาก Stateless Widget เป็น StatefulWidget เนื่องจากว่า Hot Reload นั้นไม่ได้มีการรัน main() หรือ initState() ขึ้นมาใหม่ ทำให้เมื่อเปลี่ยนประเภทไแแล้ว State จึงไม่ถูกสร้างขึ้น ส่งผลให้ทำงานผิดพลาดนั่นเอง

ซึ่งสองปัญหาข้างต้นสามารถแก้ไขได้ด้วย Option ถัดไป นั่นคือ Hot Restart นั่นเอง


Hot Restart

Hot Restart เป็นการโหลดโค้ดส่วนที่เปลี่ยนแปลงเข้าไปใน VM เช่นเดียวกับ Hot Reload แต่มีการ Restart Flutter App ทั้งหมด นั่นหมายความว่า main() จะถูกเรียกและ Render แอปพิลเคชันขึ้นมาใหม่ทั้งหมด ส่งผลให้เราสูญเสีย State ไปนั่นเอง โดยทั่วไปเรามักใช้ Hot Restart เมื่อเรามีการเปลี่ยนแปลงบางอย่างที่กระทบกับ State ทำให้วิธีนี้ใช้เวลานานขึ้นในการโหลดการเปลี่ยนแปลง


Full Restart

เป็นการหยุดแอปพลิเคชันโดยสมบูรณ์ (ทำให้ Debug Connection หายไป) และเริ่มต้นขึ้นใหม่ ส่งผลให้ใช้เวลานานที่สุด เนื่องจากต้องทำการ Compile แอปใหม่ตั้งแต่ต้น และมีการ Form debug connection ใหม่ โดยปกติเรามักจะต้อง Full Restart เมื่อเรามีการเพิ่ม Asset ใหม่ ๆ เข้าไป เช่น รูปภาพ หรือเรามีการลง Package/Plugin ใหม่ ซึ่งโค้ดไม่ได้อยู่ในแอพตั้งแต่ต้น หรืออาจจะเป็นการเปลี่ยนแปลงที่ระดับ Native (ในโฟลเดอร์ android หรือ ios) ซึ่งเราไปแก้ไข เช่น การ Declare permission ต่าง ๆ นั่นเอง


Summary

Hot Reload เป็นหลัก แต่เมื่อมีการเปลี่ยนแปลงโค้ดที่เกี่ยวข้องกับ State ให้เรา Hot Restart หากมีการแก้ไขเกี่ยวกับ Native หรือลง Package/Plugin เราต้องทำ Full Restart


📚 Hope you enjoy reading! 📚