Auto-Animate ได้เปิดตัว adapter อย่างเป็นทางการตัวแรกสำหรับ Marko 6 ช่วยให้นักพัฒนาสามารถทำแอนิเมชันการเปลี่ยนแปลงของรายการ (list changes) ได้ด้วยแท็กเพียงแท็กเดียวโดยไม่ต้องใช้ JavaScript เพิ่มเติม การเปิดตัวนี้มีความสำคัญเพราะช่วยลดโค้ดส่วนเกิน (boilerplate) ที่ทำให้การทำ motion ในโปรเจกต์ Marko รู้สึกเหมือนเป็นงานพิเศษที่ต้องจัดการเป็นกรณีไปมานานแล้ว

โมเดลการเรนเดอร์ของ Marko จะข้ามขั้นตอน "hydration" ฝั่ง client ที่เฟรมเวิร์กอย่าง React หรือ Vue ต้องพึ่งพา หลังจากเซิร์ฟเวอร์ส่ง HTML ไปแล้ว Marko จะดำเนินการต่อจาก markup นั้นในที่เดิมทันที ซึ่งช่วยให้ขนาด bundle เล็กมาก—อยู่ที่ประมาณ 7 KB เมื่อบีบอัดแบบ gzipped สำหรับ runtime อย่างไรก็ตาม ทางลัดแบบเดียวกันนี้กลับไปขัดขวางไลบรารีแอนิเมชันหลายตัวที่ต้องรอการเรนเดอร์ฝั่ง client ก่อนจึงจะสามารถแนบเอฟเฟกต์ได้ หากไม่มีการเชื่อมต่อ (hook) เข้ากับ DOM ที่มีอยู่แล้ว นักพัฒนาจึงมักจะต้องเขียนโค้ดแบบกำหนดเอง (custom code) สำหรับการอัปเดตรายการทุกครั้ง

adapter ตัวใหม่นี้ก้าวข้ามข้อจำกัดดังกล่าวโดยการเชื่อมต่อเข้ากับ lifecycle onMount ของ Marko เมื่อคอมโพเนนต์ถูก mount ตัว adapter จะสร้าง MutationObserver ขึ้นมาเพื่อเฝ้าดูการเปลี่ยนแปลงที่ parent node ของรายการ เมื่อมีการเพิ่ม (push), กรอง (filter) หรือสลับตำแหน่ง (shuffle) ไอเทม ตัว observer จะสั่งให้ transition engine ในตัวของ auto-animate ทำงาน เพื่อสร้างแอนิเมชันการเข้า (entry), การออก (exit) และการจัดเรียงใหม่ (reorder) ที่ราบรื่นโดยอัตโนมัติ ทั้งหมดนี้เกิดขึ้นภายใต้แท็ก <auto-animate> เพียงแท็กเดียว

แท็กนี้รองรับ 3 attribute:

  • parent – ตัวแปร Marko tag ที่ชี้ไปยังคอนเทนเนอร์ของรายการ
  • options – ออบเจกต์สำหรับตั้งค่า duration, easing และการตั้งค่าเวลาอื่นๆ
  • enabled – ค่า boolean แบบ reactive ที่สามารถเปิดหรือปิดแอนิเมชันได้ในขณะ runtime

เนื่องจาก enabled เป็นแบบ reactive นักพัฒนาจึงสามารถผูกค่านี้เข้ากับ state ใดๆ และสลับการเคลื่อนไหวได้โดยไม่ต้องแตะต้อง DOM หรือเขียน handler ใหม่ ดังนั้น adapter นี้จึงให้ความยืดหยุ่นมากกว่า directive แบบ static ในขณะที่ยังคงทำงานได้อย่างแนบเนียนกับส่วนอื่นๆ ของ component tree

สำหรับทีมที่ใช้ Vite แพ็กเกจนี้อาจทำให้เกิดคำเตือน "unresolved import" การเพิ่มโค้ดต่อไปนี้ลงใน vite.config.ts จะช่วยแก้ปัญหานี้ได้:

optimizeDeps: {
  exclude: ["@formkit/auto-animate"]
}

สิ่งนี้จะบอกให้ Vite ให้ plugin ของ Marko เป็นผู้จัดการการ import แทนที่จะพยายามทำ pre-bundle

ผลลัพธ์ที่นำไปใช้ได้จริงนั้นเห็นได้ทันที รายการใน Marko ทั่วไปที่ก่อนหน้านี้ต้องใช้ hook useEffect, การสลับ class ด้วยตัวเอง และโค้ดแอนิเมชันอีกหลายบรรทัด ตอนนี้สามารถเขียนได้ดังนี้:

<auto-animate parent=items enabled=showAnimations options={duration: 300}>
  <ul>
    $ for|item| of=items
      <li>${item.name}</li>
    $ end
  </ul>
</auto-animate>

ไม่ต้องใช้ JavaScript เพิ่มเติม ไม่เพิ่มขนาด bundle และยังคงได้ motion ที่ราบรื่นเหมือนที่ auto-animate มอบให้กับเฟรมเวิร์กอื่นๆ

ใครได้ประโยชน์ และใครที่ต้องเฝ้าดู

ทีม Front-end ที่ใช้งาน Marko อยู่แล้วจะได้รับโซลูชันสำเร็จรูปสำหรับรูปแบบ UI ที่พบบ่อย นั่นคือรายการแบบไดนามิก (dynamic lists) ความเบาของ adapter ช่วยรักษาจุดเด่นของ Marko ในเรื่องขนาด bundle ที่เล็กมาก ซึ่งสำคัญอย่างยิ่งสำหรับเว็บไซต์ที่เน้นประสิทธิภาพสูง ในทางกลับกัน ปัจจุบัน adapter นี้เน้นไปที่การเปลี่ยนแปลงของรายการ (list mutations) เท่านั้น นักพัฒนาที่ต้องการการควบคุม timeline แบบเฉพาะเจาะจงหรือการจัดท่าทาง (choreography) ที่ซับซ้อน ยังคงต้องกลับไปใช้โค้ดแบบกำหนดเองหรือไลบรารีอื่น

สิ่งที่ต้องจับตามองต่อไป

adapter นี้เป็น open-source และมี demo sandbox ลิงก์มาจาก release notes แล้ว ความคิดเห็นจากชุมชนน่าจะมีส่วนในการกำหนดส่วนขยายในอนาคต เช่น การรองรับ grid reflows หรือการรวมเข้ากับ component-level transitions ที่กำลังจะมาของ Marko หากอัตราการใช้งานเติบโตเหมือนกับการตอบรับอย่างรวดเร็วของ auto-animate ใน React และ Vue เราอาจได้เห็นการผลักดันการทำ motion แบบ "zero-code" ที่กว้างขวางขึ้นในระบบนิเวศของ JavaScript UI

สรุป: adapter สำหรับ Marko 6 ของ Auto-Animate เปลี่ยนงานที่เคยยุ่งยากในอดีต—นั่นคือการทำแอนิเมชันให้กับรายการที่เรนเดอร์จากเซิร์ฟเวอร์—ให้กลายเป็นแท็กแบบ declarative เพียงแท็กเดียว โดยยังคงรักษาขนาด bundle ที่เล็กจิ๋วของ Marko ไว้ ในขณะที่มอบเลเยอร์การเคลื่อนไหวที่ใช้งานได้ทันทีและสลับเปิดปิดได้ให้กับนักพัฒนา