การทำ Animation ด้วย CSS height อย่างง่ายในแอป Electron สำหรับจดบันทึกที่ชื่อ Granola กิน CPU ถึง 60% และ GPU 25% บน MacBook M2 ทำให้เกิดการสืบสวนเชิงลึกเกี่ยวกับการปรับปรุงประสิทธิภาพเว็บ ตัวการคือ audio visualizer เล็กๆ ที่มีแท่งเต้นรำ 3 แท่งซึ่งใช้ transition: height 300ms ease in out
เพื่อทำ animation การเปลี่ยนแปลงความสูง
การเปรียบเทียบผลกระทบต่อประสิทธิภาพ:
- ก่อนการปรับปรุง: CPU 60%, GPU 25% บน MacBook M2
- หลังการปรับปรุง: CPU 6%, GPU <1% บน MacBook M2
- รายละเอียดการเรนเดอร์: ระบบ 47ms, การเรนเดอร์ 45ms, การวาด 20ms, การประมวลผลสคริปต์ 13ms
![]() |
---|
ปัญหาประสิทธิภาพที่เกิดจากแอนิเมชันความสูง CSS ในแอปจดบันทึก |
Browser Rendering Pipeline สร้างคอขวดด้านประสิทธิภาพ
ปัญหาประสิทธิภาพเกิดจากวิธีที่เบราว์เซอร์จัดการ CSS properties ประเภทต่างๆ ในระหว่างการทำ animation เมื่อทำ animation ความสูง เบราว์เซอร์ต้องคำนวณ layout ของทั้งหน้าใหม่ repaint elements ที่ได้รับผลกระทบ และจากนั้น composite รูปภาพสุดท้าย สิ่งนี้ทำให้ height เป็น layout property ซึ่งเป็นประเภทที่แพงที่สุดในการทำ animation นักพัฒนาค้นพบว่าแม้หลังจากการปรับปรุงแล้ว ฟีเจอร์นี้ยังคงกิน CPU 6% ซึ่งหลายคนในชุมชนเห็นว่ามากเกินไปสำหรับ visual element ที่เรียบง่ายเช่นนี้
Rendering pipeline มี 3 ขั้นตอนหลัก: Layout (ตัดสินใจว่า elements จะไปอยู่ที่ไหน), Painting (วาด elements ลงบน layers), และ Compositing (รวม layers เข้าด้วยกัน) การเปลี่ยนแปลง Height จะเรียกใช้ทั้งสามขั้นตอน ในขณะที่ properties อย่าง transform
และ opacity
ต้องการเพียง compositing เท่านั้น ทำให้มีประสิทธิภาพมากกว่า
ลำดับชั้นประสิทธิภาพของ CSS Property:
- Layout Properties (แพงที่สุด): height, width, margin, padding - ทำให้เกิด layout + paint + composite
- Paint Properties (ปานกลาง): fill, stroke, colors - ทำให้เกิด paint + composite
- Composite Properties (ถูกที่สุด): transform, opacity - ทำให้เกิด composite เท่านั้น
![]() |
---|
การวิเคราะห์เลเยอร์การเรนเดอร์และผลกระทบต่อประสิทธิภาพที่เกี่ยวข้องกับ CSS animations |
ชุมชนต่อต้านการใช้ทรัพยากร
ชุมชนนักพัฒนาแสดงความกังวลอย่างมากเกี่ยวกับการใช้ทรัพยากร แม้หลังจากการปรับปรุงแล้ว นักพัฒนาหลายคนตั้งคำถามว่าทำไมแอปจดบันทึกถึงต้องการ animation ที่เข้มข้นเช่นนี้ โดยแนะนำทางเลือกที่เรียบง่ายกว่าอย่าง animated GIFs หรือ static icons การอภิปรายเผยให้เห็นความผิดหวังในวงกว้างต่อแนวทางการพัฒนาเว็บสมัยใหม่ที่ให้ความสำคัญกับ visual effects มากกว่าประสิทธิภาพ
ฉันอยากให้มันเปลี่ยนจากจุดสีเทาเป็นจุดสีแดง 'recording' มากกว่าที่จะใช้แม้แต่ 6% ที่ผู้เขียนตัดสินใจว่า 'แก้ไขแล้ว' ใน 99% ของกรณี ฉันไม่สนใจเลยเกี่ยวกับ 'artistic vision' ของ UI designer
สมาชิกชุมชนหลายคนเสนอแนวทางแก้ไขในระดับเบราว์เซอร์เพื่อจำกัดการใช้ทรัพยากรโดยเว็บไซต์ รวมถึงกลไก CPU throttling และการควบคุมของผู้ใช้เพื่อปิดใช้งาน animations ที่แพง นักพัฒนาบางคนแบ่งปันเทคนิคอย่างการใช้ CSS contain
properties หรือ overflow: hidden
containers เพื่อจำกัดขอบเขตของการคำนวณ layout ใหม่
ทางเลือกอื่นที่แนะนำ:
- Animated GIF (เทคโนโลยีเก่าแต่มีประสิทธิภาพสำหรับแอนิเมชันง่ายๆ)
- การเรนเดอร์แบบ Canvas-based
- คุณสมบัติ CSS
contain: strict
หรือcontain: content
- คอนเทนเนอร์
overflow: hidden
เพื่อจำกัดขอบเขตของเลย์เอาต์ - ไอคอนแบบคงที่แทนการใช้แอนิเมชัน
![]() |
---|
การใช้ทรัพยากรในแอปจดบันทึก เผยให้เห็นความต้องการ CPU และ GPU ที่สูง |
ทางเลือกอื่นและวิธีแก้ไขทางเทคนิค
นักพัฒนาแก้ปัญหาในที่สุดด้วยการสร้างภาพลวงตาโดยใช้สี่เหลี่ยมมุมมน 2 อันที่เคลื่อนที่ในทิศทางตรงข้ามด้วย transform
properties หลีกเลี่ยงการเปลี่ยนแปลงความสูงทั้งหมด อย่างไรก็ตาม สมาชิกชุมชนหลายคนแนะนำแนวทางที่มีประสิทธิภาพมากกว่านี้ รวมถึง canvas-based animations, GIFs ธรรมดา หรือกลยุทธ์ CSS containment
การอภิปรายเน้นย้ำช่องว่างความรู้ในชุมชนนักพัฒนาเกี่ยวกับการปรับปรุง browser rendering ในขณะที่นักพัฒนาบางคนถือว่านี่เป็นความรู้พื้นฐาน คนอื่นๆ ชี้ให้เห็นว่าการปรับปรุงประสิทธิภาพมักจะถูกมองข้ามเพื่อการพัฒนาฟีเจอร์และการออกแบบภาพในเวิร์กโฟลว์การพัฒนาเว็บสมัยใหม่
เหตุการณ์นี้เป็นการเตือนใจว่า CSS animations ที่ดูไร้เดียงสาสามารถส่งผลกระทบต่อประสิทธิภาพอย่างมีนัยสำคัญ โดยเฉพาะในแอปพลิเคชัน Electron ที่การปรับปรุงทุกอย่างมีความสำคัญต่อประสบการณ์ผู้ใช้และอายุแบตเตอรี่
อ้างอิง: Don't animate height!