ทำไมภาพเคลื่อนไหวบางภาพจึงทำงานช้า

เบราว์เซอร์สมัยใหม่สามารถสร้างภาพเคลื่อนไหวให้กับพร็อพเพอร์ตี้ CSS ได้ 2 รายการในราคาไม่แพง ได้แก่ transform และ opacity ถ้าหากคุณทำให้สิ่งอื่นเคลื่อนไหว คุณอาจจะไม่ไปถึงเฟรม 60 เฟรมต่อวินาที (FPS) ที่ลื่นไหลไม่มีสะดุด โพสต์นี้จะอธิบายสาเหตุ

เป็นที่ยอมรับกันโดยทั่วไปว่าอัตราเฟรม 60 FPS เป็นเป้าหมายเมื่อสร้างภาพเคลื่อนไหวบนเว็บ อัตราเฟรมนี้จะช่วยให้ภาพเคลื่อนไหวดูราบรื่น ในเว็บ เฟรมคือเวลาที่ใช้ในการทํางานทั้งหมดที่จําเป็นในการอัปเดตและวาดหน้าจอใหม่ หากแต่ละเฟรมแสดงไม่เสร็จภายใน 16.7 มิลลิวินาที (1,000 มิลลิวินาที / 60 ≈ 16.7) ผู้ใช้จะรับรู้ถึงความล่าช้า

ไปป์ไลน์การแสดงผล

หากต้องการแสดงข้อมูลในหน้าเว็บ เบราว์เซอร์จะต้องทำตามขั้นตอนตามลำดับต่อไปนี้

  1. สไตล์: คํานวณสไตล์ที่ใช้กับองค์ประกอบ
  2. เลย์เอาต์: สร้างเรขาคณิตและตำแหน่งสำหรับแต่ละองค์ประกอบ
  3. ระบายสี: เติมพิกเซลขององค์ประกอบแต่ละรายการลงในเลเยอร์
  4. คอมโพสิต: วาดเลเยอร์ไปยังหน้าจอ

ทั้ง 4 ขั้นตอนนี้เรียกว่าไปป์ไลน์การแสดงผลของเบราว์เซอร์

เมื่อทำให้บางสิ่งบางอย่างเป็นภาพเคลื่อนไหวในหน้าเว็บที่โหลดแล้ว ขั้นตอนเหล่านี้จะต้องเกิดขึ้นอีกครั้ง กระบวนการนี้เริ่มจากขั้นตอนที่ต้องเปลี่ยนแปลงเพื่อให้ภาพเคลื่อนไหวแสดงได้

ดังที่ได้กล่าวไปก่อนหน้านี้ ขั้นตอนเหล่านี้เป็นขั้นตอนตามลำดับ เช่น หากคุณสร้างภาพเคลื่อนไหวของสิ่งที่เปลี่ยนแปลงเลย์เอาต์ ขั้นตอนเพนต์และคอมโพสิตก็จะต้องทำงานอีกครั้งด้วย การสร้างภาพเคลื่อนไหวของสิ่งที่เปลี่ยนแปลงเลย์เอาต์จึงมีค่าใช้จ่ายสูงกว่าการสร้างภาพเคลื่อนไหวของสิ่งที่เปลี่ยนแปลงเฉพาะการคอมโพส

การทำให้เป็นภาพเคลื่อนไหวของพร็อพเพอร์ตี้เลย์เอาต์

การเปลี่ยนแปลงเลย์เอาต์เกี่ยวข้องกับการคำนวณเรขาคณิต (ตำแหน่งและขนาด) ขององค์ประกอบทั้งหมดที่ได้รับผลกระทบจากการเปลี่ยนแปลง ถ้าคุณเปลี่ยนองค์ประกอบหนึ่ง อาจต้องคำนวณเรขาคณิตขององค์ประกอบอื่นๆ ด้วย เช่น หากคุณเปลี่ยนความกว้างขององค์ประกอบ <html> องค์ประกอบย่อยขององค์ประกอบดังกล่าวอาจได้รับผลกระทบ เนื่องจากองค์ประกอบจะแสดงเกินขอบเขตและส่งผลต่อกันและกัน บางครั้งการเปลี่ยนแปลงที่ต่ำลงมาในลําดับชั้นอาจส่งผลให้มีการคำนวณเลย์เอาต์ตั้งแต่ต้นจนจบ

ยิ่งลําดับชั้นขององค์ประกอบที่มองเห็นมีขนาดใหญ่เท่าใด การคํานวณเลย์เอาต์ก็จะใช้เวลานานขึ้นเท่านั้น

การทำให้ลูกปัดเคลื่อนไหว

Paint คือกระบวนการกำหนดลำดับที่องค์ประกอบควรแสดงบนหน้าจอ ซึ่งมักจะเป็นงานที่ใช้เวลานานที่สุดในบรรดางานทั้งหมดในไปป์ไลน์

การวาดภาพส่วนใหญ่ในเบราว์เซอร์สมัยใหม่จะดำเนินการในโปรแกรมแรสเตอร์ ทั้งนี้ขึ้นอยู่กับวิธีจัดกลุ่มองค์ประกอบในแอปเป็นเลเยอร์ คุณอาจต้องระบายสีองค์ประกอบอื่นๆ นอกเหนือจากที่เปลี่ยนแปลงด้วย ทั้งนี้ขึ้นอยู่กับวิธีจัดกลุ่มองค์ประกอบในแอป

การทำภาพเคลื่อนไหวของพร็อพเพอร์ตี้คอมโพสิต

การประกอบเป็นกระบวนการแยกหน้าเว็บออกเป็นเลเยอร์ต่างๆ แปลงข้อมูลที่หน้าเว็บควรมีลักษณะเป็นพิกเซล (การแรสเตอร์) และนำเลเยอร์มาประกอบกันเพื่อสร้างหน้าเว็บ (การประกอบหน้าเว็บ)

ด้วยเหตุนี้ พร็อพเพอร์ตี้ opacity จึงรวมอยู่ในรายการสิ่งที่สร้างภาพเคลื่อนไหวได้แบบประหยัด ตราบใดที่พร็อพเพอร์ตี้นี้อยู่ในเลเยอร์ของตัวเอง GPU จะจัดการการเปลี่ยนแปลงกับพร็อพเพอร์ตี้ดังกล่าวได้ในระหว่างขั้นตอนการสร้างองค์ประกอบ เบราว์เซอร์แบบ Chromium และ WebKit จะสร้างเลเยอร์ใหม่สำหรับองค์ประกอบที่มีการเปลี่ยนหรือภาพเคลื่อนไหว CSS ใน opacity

เลเยอร์คืออะไร

การวางสิ่งที่จะเป็นภาพเคลื่อนไหวหรือมีการเปลี่ยนรูปแบบลงในเลเยอร์ใหม่ทำให้เบราว์เซอร์ต้องวาดเฉพาะรายการเหล่านั้นเท่านั้น โดยไม่ต้องวาดทุกอย่าง คุณอาจคุ้นเคยกับแนวคิดของ Photoshop เกี่ยวกับเลเยอร์ที่มีองค์ประกอบมากมายที่ย้ายด้วยกันได้ เลเยอร์การแสดงผลของเบราว์เซอร์คล้ายกับแนวคิดนี้

แม้ว่าเบราว์เซอร์จะตัดสินใจได้ดีว่าองค์ประกอบใดควรอยู่ในเลเยอร์ใหม่ แต่หากพลาดองค์ประกอบใดไป ก็ยังมีวิธีบังคับให้สร้างเลเยอร์ได้ คุณสามารถดูข้อมูลนี้ได้ในวิธีสร้างภาพเคลื่อนไหวประสิทธิภาพสูง อย่างไรก็ตาม คุณควรสร้างเลเยอร์ใหม่อย่างระมัดระวังเนื่องจากแต่ละเลเยอร์ใช้หน่วยความจำ ในอุปกรณ์ที่มีหน่วยความจำจํากัด การสร้างเลเยอร์ใหม่อาจทําให้เกิดปัญหาด้านประสิทธิภาพมากกว่าปัญหาที่คุณพยายามจะแก้ไข นอกจากนี้ยังต้องอัปโหลดพื้นผิวของแต่ละเลเยอร์ไปยัง GPU คุณจึงอาจพบข้อจำกัดของแบนด์วิดท์ระหว่าง CPU และ GPU

ประสิทธิภาพของ CSS เทียบกับ JavaScript

คุณอาจสงสัยว่าการใช้ CSS หรือ JavaScript สำหรับภาพเคลื่อนไหวนั้นดีกว่ากันในแง่ประสิทธิภาพ

โดยทั่วไปภาพเคลื่อนไหวแบบ CSS และภาพเคลื่อนไหวบนเว็บ (ในเบราว์เซอร์ที่รองรับ API) จะมีการจัดการในชุดข้อความที่เรียกว่าชุดข้อความประกอบ ซึ่งแตกต่างจากเธรดหลักของเบราว์เซอร์ที่ใช้สำหรับเรียกใช้การจัดสไตล์ เลย์เอาต์ การวาดภาพ และ JavaScript ซึ่งหมายความว่าหากเบราว์เซอร์กำลังทำงานบางอย่างที่ต้องใช้ทรัพยากรมากในเธรดหลัก ภาพเคลื่อนไหวเหล่านี้จะทำงานต่อไปได้โดยไม่หยุดชะงัก

ตามที่อธิบายไว้ในบทความนี้ การเปลี่ยนแปลงอื่นๆ ในการเปลี่ยนรูปแบบและความทึบแสงจะจัดการโดยเธรดคอมโพสิตในหลายกรณีด้วย

หากภาพเคลื่อนไหวทริกเกอร์การวาด เลย์เอาต์ หรือทั้ง 2 อย่าง เทรดหลักจะต้องทํางาน กรณีนี้ใช้ได้กับทั้งภาพเคลื่อนไหว CSS และ JavaScript และค่าใช้จ่ายเพิ่มเติมของเลย์เอาต์หรือการวาดภาพมีแนวโน้มที่จะน้อยกว่างานใดๆ ที่เชื่อมโยงกับการดำเนินการของ CSS หรือ JavaScript จึงทำให้คำถามนี้ไม่มีความหมาย