หลีกเลี่ยงการทาสีที่ไม่จำเป็น

บทนำ

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

ภาพวาด: ทัวร์ชมแบบย่อ

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

กระบวนการวาดภาพก็น่าสนใจ ใน Chrome ต้นไม้ DOM และ CSS ที่รวมกันจะได้รับการแรสเตอร์โดยซอฟต์แวร์บางอย่างที่เรียกว่า Skia หากคุณเคยเล่นกับองค์ประกอบ canvas มาก่อน API ของ Skia จะดูคุ้นเคยมากสำหรับคุณ เนื่องจากมีฟังก์ชันสไตล์ moveTo และ lineTo จำนวนมาก รวมถึงฟังก์ชันขั้นสูงอีกมากมาย โดยพื้นฐานแล้ว องค์ประกอบทั้งหมดที่ต้องวาดจะได้รับการกลั่นให้เป็นคอลเล็กชันการเรียกใช้ Skia ที่เรียกใช้ได้ และเอาต์พุตคือบิตแมปจำนวนมาก ระบบจะอัปโหลดบิตแมปเหล่านี้ไปยัง GPU และ GPU จะช่วยจัดวางองค์ประกอบเข้าด้วยกันเพื่อให้ได้ภาพสุดท้ายบนหน้าจอ

DOM เป็นพิกเซล

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

อย่างไรก็ตาม การวางสีต้องใช้เวลา และหากไม่ลดจำนวนลง เราจะใช้งบประมาณเฟรมประมาณ 16 มิลลิวินาทีเกิน ผู้ใช้จะสังเกตได้ว่าเราพลาดเฟรมและเห็นว่ามันกระตุก ซึ่งส่งผลเสียต่อประสบการณ์ของผู้ใช้แอปของเราในท้ายที่สุด เราไม่ต้องการเช่นนี้ ดังนั้นมาดูกันว่ามีปัจจัยใดบ้างที่ทำให้การลงสีจำเป็นต้องทำงาน และเราสามารถทำสิ่งใดได้บ้าง

การเลื่อน

เมื่อใดก็ตามที่คุณเลื่อนขึ้นหรือลงในเบราว์เซอร์ คุณจะต้องระบายสีเนื้อหาใหม่อีกครั้งก่อนที่จะปรากฏบนหน้าจอ ในกรณีนี้ พื้นที่ที่จะวาดจะมีขนาดเล็ก แต่ถึงอย่างนั้น องค์ประกอบที่ต้องวาดก็อาจใช้สไตล์ที่ซับซ้อนได้ ดังนั้น การที่คุณต้องทาสีพื้นที่เล็กๆ ไม่ได้หมายความว่าคุณจะทาสีเสร็จได้อย่างรวดเร็ว

หากต้องการดูว่ามีการทาสีส่วนใดใหม่ คุณสามารถใช้ฟีเจอร์ “แสดงสี่เหลี่ยมผืนผ้าสี” ในเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome (เพียงกดปุ่มเฟืองเล็กๆ ที่มุมขวาล่าง) จากนั้นเมื่อเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่ ให้โต้ตอบกับหน้าเว็บ แล้วคุณจะเห็นสี่เหลี่ยมผืนผ้ากะพริบแสดงตําแหน่งและเวลาที่ Chrome วาดส่วนหนึ่งของหน้าเว็บ

แสดงสี่เหลี่ยมผืนผ้าในการแสดงผลในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
แสดงสี่เหลี่ยมผืนผ้าสีในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

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

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

การโต้ตอบ

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

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

ชุดค่าผสมที่โชคร้าย

การสาธิตที่ใช้สีราคาแพง
การสาธิตที่ใช้สีราคาแพง

จะเกิดอะไรขึ้นหากฉันเลื่อนและเมาส์ไปพร้อมๆ กัน ฉันอาจโต้ตอบกับองค์ประกอบโดยไม่ได้ตั้งใจขณะเลื่อนผ่านองค์ประกอบนั้น ซึ่งจะทริกเกอร์การทาสีที่มีราคาแพง ซึ่งอาจทำให้ใช้เฟรมเกินงบประมาณประมาณ 16.7 มิลลิวินาที (เวลาที่เราต้องอยู่ต่ำกว่านั้นเพื่อให้ได้ 60 เฟรมต่อวินาที) เราได้สร้างเดโมเพื่อแสดงให้คุณเห็นถึงสิ่งที่เราหมายถึง เราหวังว่าเมื่อเลื่อนและเลื่อนเมาส์ คุณจะเห็นเอฟเฟกต์การวางเมาส์เหนือรายการทำงาน แต่มาดูกันว่าเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome แสดงผลอย่างไร

เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome ที่แสดงเฟรมราคาแพง
เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome ที่แสดงเฟรมราคาแพง

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

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

โค้ดมีดังนี้

// Used to track the enabling of hover effects
var enableTimer = 0;

/*
 * Listen for a scroll and use that to remove
 * the possibility of hover effects
 */
window.addEventListener('scroll', function() {
  clearTimeout(enableTimer);
  removeHoverClass();

  // enable after 1 second, choose your own value here!
  enableTimer = setTimeout(addHoverClass, 1000);
}, false);

/**
 * Removes the hover class from the body. Hover styles
 * are reliant on this class being present
 */
function removeHoverClass() {
  document.body.classList.remove('hover');
}

/**
 * Adds the hover class to the body. Hover styles
 * are reliant on this class being present
 */
function addHoverClass() {
  document.body.classList.add('hover');
}

คุณจะเห็นได้ว่าเราใช้คลาสในเนื้อความเพื่อติดตามว่าเอฟเฟกต์การวางเมาส์ "อนุญาต" หรือไม่ และรูปแบบเบื้องหลังจะใช้คลาสนี้เพื่อแสดง

/* Expect the hover class to be on the body
 before doing any hover effects */
.hover .block:hover {
 
}

เท่านี้ก็เรียบร้อย

บทสรุป

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

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

ลองดูเว็บไซต์และแอปพลิเคชันของคุณว่าควรได้รับการปกป้องสีเล็กน้อยไหม