เราสร้างข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพได้อย่างไรและเพราะเหตุใด

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

ALT_TEXT_HERE

เหตุใดจึงต้องสร้างแผงอื่น

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

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

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

ลิงก์ความคิดเห็นในแผง

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

วิธีที่เราสร้างข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพ

เช่นเดียวกับเครื่องมืออื่นๆ ของ DevTools เราได้สร้างข้อมูลเชิงลึกด้านประสิทธิภาพใน TypeScript และใช้คอมโพเนนต์เว็บที่รองรับ lit-html เพื่อสร้างอินเทอร์เฟซผู้ใช้ สิ่งที่แตกต่างออกไปคืออินเทอร์เฟซ UI หลักเป็นองค์ประกอบ HTML canvas และไทม์ไลน์จะวาดบนผืนผ้าใบนี้ ความซับซ้อนส่วนใหญ่มาจากการจัดการผืนผ้าใบนี้ ซึ่งไม่เพียงวาดรายละเอียดที่ถูกต้องในตำแหน่งที่ถูกต้องเท่านั้น แต่ยังจัดการเหตุการณ์เมาส์ด้วย (เช่น ผู้ใช้คลิกที่ใดบนผืนผ้าใบ ผู้ใช้คลิกเหตุการณ์ที่เราวาดไว้ไหม) และตรวจสอบว่าเราแสดงผลแคนวาสอีกครั้งอย่างมีประสิทธิภาพ

แทร็กหลายรายการในผืนผ้าใบเดียว

สำหรับเว็บไซต์หนึ่งๆ มี "แทร็ก" หลายแทร็กที่เราต้องการแสดงผล โดยแต่ละแทร็กจะแทนหมวดหมู่ของข้อมูลที่แตกต่างกัน เช่น แผงข้อมูลเชิงลึกจะแสดงแทร็ก 3 แทร็กโดยค่าเริ่มต้น ดังนี้

และในขณะที่เราขยายการให้บริการฟีเจอร์ต่างๆ ในแผงดังกล่าว เราก็คาดว่าจะมีการเพิ่มแทร็กเพิ่มเติม

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

องค์ประกอบ canvas ใช้เวลาในการ (แสดงผลอีกครั้ง) นาน การมีภาพพิมพ์แคนวาสหลายภาพจะใช้เวลานานกว่าภาพพิมพ์แคนวาสภาพเดียว แม้ว่าภาพพิมพ์แคนวาสนั้นจะใหญ่กว่าก็ตาม การแสดงผลการวางซ้อนในหลายแทร็ก (เช่น เส้นแนวตั้งเพื่อระบุเหตุการณ์ เช่น เวลา FCP) จะมีความซับซ้อน เนื่องจากเราต้องแสดงผลในหลายผืนผ้าใบและตรวจสอบว่าผืนผ้าใบทั้งหมดแสดงผลร่วมกันและจัดแนวอย่างถูกต้อง

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

canvasContext.beginPath();
canvasContext.rect(
    trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();

นอกจากนี้ เรายังไม่ต้องการให้แต่ละแทร็กต้องทราบตำแหน่งแนวตั้งของตัวเองด้วย โดยแต่ละแทร็กควรแสดงผลราวกับว่ากำลังแสดงผลที่ (0, 0) และเรามีคอมโพเนนต์ระดับที่สูงขึ้น (ซึ่งเราเรียกว่า TrackManager) เพื่อจัดการตำแหน่งแทร็กโดยรวม ซึ่งทำได้ด้วย translate ซึ่งจะแปลแคนวาสตามตำแหน่ง (x, y) ที่ระบุ เช่น

canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide

แม้ว่าจะมีการตั้งค่าโค้ด rect 0, 0 เป็นตำแหน่ง แต่การแปลโดยรวมที่ใช้จะทำให้รูปสี่เหลี่ยมผืนผ้าแสดงผลที่ 0, 10 วิธีนี้ช่วยให้เราทำงานกับแต่ละแทร็กได้ราวกับว่าเรากำลังเรนเดอร์ที่ (0, 0) และผู้จัดการแทร็กจะแปลขณะเรนเดอร์แต่ละแทร็กเพื่อให้แน่ใจว่าแต่ละแทร็กจะเรนเดอร์อย่างถูกต้องใต้แทร็กก่อนหน้า

แคนวาสนอกหน้าจอสำหรับแทร็กและไฮไลต์

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

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

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

ในการแก้ปัญหานี้ เราได้แบ่ง UI ออกเป็นผืนผ้าใบนอกหน้าจอ 2 ใบ ได้แก่ แคนวาส "หลัก" ตำแหน่งที่แทร็กแสดงผล และผืนผ้าใบ "ไฮไลต์" ที่มีการวาดไฮไลต์ จากนั้นเราจะแสดงผลโดยการคัดลอกผืนผ้าใบเหล่านั้นไปยังผืนผ้าใบเดียวที่แสดงบนหน้าจอต่อผู้ใช้ เราสามารถใช้เมธอด drawImage กับบริบทของ Canvas ซึ่งอาจใช้ Canvas อีกรายการเป็นต้นฉบับได้

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

การแยกวิเคราะห์การติดตามที่ผ่านการทดสอบอย่างครอบคลุม

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

แยกวิเคราะห์ไฟล์การติดตามและดึงข้อมูลที่จําเป็น แสดงผลชุดแทร็ก

การแยกการแยกวิเคราะห์ (ส่วนที่ 1) ออกจากการทำงานของ UI (ส่วนที่ 2) ช่วยให้เราสามารถสร้างระบบการแยกวิเคราะห์ที่มีประสิทธิภาพได้ การติดตามแต่ละรายการจะทำงานผ่านชุด Handler ซึ่งมีหน้าที่รับผิดชอบต่อข้อกังวลที่แตกต่างกัน โดย LayoutShiftHandler จะคํานวณข้อมูลทั้งหมดที่จําเป็นสําหรับการเปลี่ยนเลย์เอาต์ และ NetworkRequestsHandler จะจัดการเฉพาะการดึงคําขอเครือข่าย การมีขั้นตอนการแยกวิเคราะห์ที่ชัดเจนนี้ซึ่งมีตัวแฮนเดิลต่างๆ ที่รับผิดชอบส่วนต่างๆ ของการติดตามก็มีประโยชน์เช่นกัน เนื่องจากการแยกวิเคราะห์การติดตามอาจมีความซับซ้อนมาก และช่วยให้คุณมุ่งเน้นที่ข้อกังวลหนึ่งๆ ได้ในแต่ละครั้ง

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

การทดสอบภาพหน้าจอสําหรับ UI ของ Canvas

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

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

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

บทสรุป

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

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

ดาวน์โหลดเวอร์ชันตัวอย่าง

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

ติดต่อทีม Chrome DevTools

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