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

เกริ่นนำ

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

การวาดภาพ: ทัวร์ชมที่รวดเร็วมาก

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

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

Dom เป็นพิกเซล

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

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

การเลื่อน

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

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

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

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

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

การโต้ตอบ

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

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

ชุดค่าผสมที่ไม่น่าพอใจ

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

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

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

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

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

ต่อไปนี้เป็นรหัส:

// 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 มิลลิวินาทีเสมอ เพื่อให้ดำเนินการดังกล่าวได้ คุณควรผสานรวมการใช้เครื่องมือสำหรับนักพัฒนาเว็บตลอดทั้งกระบวนการพัฒนาเพื่อระบุและแก้ไขจุดคอขวดที่เกิดขึ้น

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

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