การแก้ปัญหา CLS ในเว็บไซต์อีคอมเมิร์ซ Next.js-Powered (กรณีศึกษา)
เผยแพร่แล้ว: 2022-03-10Fairprice เป็นหนึ่งในร้านขายของชำออนไลน์ที่ใหญ่ที่สุดในสิงคโปร์ เรามองหาโอกาสในการปรับปรุงประสบการณ์การช็อปปิ้งออนไลน์ของผู้ใช้อย่างต่อเนื่อง ประสิทธิภาพเป็นหนึ่งในองค์ประกอบหลักเพื่อให้แน่ใจว่าผู้ใช้ของเราจะมีประสบการณ์การใช้งานที่น่าพึงพอใจโดยไม่คำนึงถึงอุปกรณ์หรือการเชื่อมต่อเครือข่าย
มีตัวบ่งชี้ประสิทธิภาพหลัก (KPI) มากมายที่วัดจุดต่างๆ ในช่วงวงจรชีวิตของหน้าเว็บ (เช่น TTFB, domInteractive
และ onload
) แต่ตัวชี้วัดเหล่านี้ไม่ได้สะท้อนถึงประสบการณ์ของผู้ใช้ปลายทางที่มีต่อหน้าเว็บ
เราต้องการใช้ KPI สองสามตัวที่สอดคล้องกับประสบการณ์จริงของผู้ใช้ปลายทางอย่างใกล้ชิด ดังนั้นเราจึงรู้ว่าหาก KPI เหล่านั้นทำงานได้ไม่ดี ก็จะส่งผลกระทบโดยตรงต่อประสบการณ์ของผู้ใช้ปลายทาง เราพบว่าเมตริกประสิทธิภาพที่เน้นผู้ใช้เป็นศูนย์กลางนั้นเหมาะสมที่สุดสำหรับจุดประสงค์นี้
มีเมตริกประสิทธิภาพที่เน้นผู้ใช้เป็นศูนย์กลางมากมายในการวัดจุดต่างๆ ในวงจรชีวิตของเพจ เช่น FCP, LCP, FID, CLS และอื่นๆ สำหรับกรณีศึกษานี้ เราจะเน้นที่ CLS เป็นหลัก
CLS วัดคะแนนรวมของการเปลี่ยนแปลงเค้าโครงที่ไม่คาดคิดทั้งหมดที่เกิดขึ้นระหว่างเวลาที่หน้าเริ่มโหลดและจนกว่าจะยกเลิกการโหลด
“
ดังนั้น การมีค่า CLS ต่ำสำหรับหน้าจะช่วยให้แน่ใจว่าไม่มีการสุ่มกะรูปแบบที่ก่อให้เกิดความหงุดหงิดใจของผู้ใช้ Barry Pollard ได้เขียนบทความเชิงลึกที่ยอดเยี่ยมเกี่ยวกับ CLS
เราค้นพบปัญหา CLS ในหน้าผลิตภัณฑ์ของเราอย่างไร
เราใช้ Lighthouse และ WebPagetest เป็นเครื่องมือทดสอบสังเคราะห์ของเราสำหรับประสิทธิภาพในการวัด CLS เรายังใช้ไลบรารี่ web-vitals เพื่อวัด CLS สำหรับผู้ใช้จริง นอกจากนั้น เราจะตรวจสอบส่วนรายงาน Core Web Vitals ของ Google Search Console เพื่อรับทราบแนวคิดเกี่ยวกับปัญหา CLS ที่อาจเกิดขึ้นในหน้าใดๆ ของเรา ขณะสำรวจส่วนรายงาน เราพบว่า URL จำนวนมากจากหน้ารายละเอียดผลิตภัณฑ์มีค่า CLS มากกว่า 0.1 ซึ่งบ่งบอกว่ามีเหตุการณ์การเปลี่ยนแปลงรูปแบบที่สำคัญเกิดขึ้นที่นั่น
การดีบักปัญหา CLS โดยใช้เครื่องมือต่างๆ
ตอนนี้เราทราบแล้วว่ามีปัญหา CLS ในหน้ารายละเอียดผลิตภัณฑ์ ขั้นตอนต่อไปคือการระบุว่าองค์ประกอบใดเป็นสาเหตุ ในตอนแรก เราตัดสินใจทำการทดสอบโดยใช้เครื่องมือทดสอบสังเคราะห์
ดังนั้นเราจึงวิ่งประภาคารเพื่อตรวจสอบว่าสามารถพบองค์ประกอบใด ๆ ที่อาจทำให้เกิดการเปลี่ยนแปลงรูปแบบที่สำคัญหรือไม่ รายงาน CLS เป็น .004 ซึ่งค่อนข้างต่ำ
หน้ารายงาน Lighthouse มีส่วนการวินิจฉัย ซึ่งยังไม่แสดงองค์ประกอบใด ๆ ที่ทำให้เกิดค่า CLS สูง
จากนั้นเราก็รัน WebpageTest และตัดสินใจตรวจสอบมุมมองแถบฟิล์ม:
เราพบว่าคุณลักษณะนี้มีประโยชน์มากเนื่องจากเราสามารถค้นหาว่าองค์ประกอบใดที่ทำให้เค้าโครงเปลี่ยนไปในช่วงเวลาใด แต่เมื่อเราทำการทดสอบเพื่อดูว่ามีการเน้นการเลื่อนเลย์เอาต์ใดๆ หรือไม่ ก็ไม่ได้มีส่วนทำให้เกิด LCS ขนาดใหญ่:
จุดเด่นของ CLS คือการบันทึกคะแนนการเปลี่ยนเลย์เอาต์แต่ละรายการตลอดอายุการใช้งานของหน้าและเพิ่มเข้าไป
“
หมายเหตุ : วิธีวัด CLS มีการเปลี่ยนแปลงตั้งแต่เดือนมิถุนายน พ.ศ. 2564
เนื่องจาก Lighthouse และ WebpageTest ตรวจไม่พบองค์ประกอบใดๆ ที่ทริกเกอร์การเปลี่ยนเลย์เอาต์หลัก ซึ่งหมายความว่าเกิดขึ้นหลังจากการโหลดหน้าแรกซึ่งอาจเกิดจากการกระทำบางอย่างของผู้ใช้ ดังนั้นเราจึงตัดสินใจใช้ส่วนขยาย Web Vitals Google Chrome เนื่องจากสามารถบันทึก CLS บนหน้าในขณะที่ผู้ใช้โต้ตอบกับมัน หลังจากดำเนินการต่างๆ เราพบว่าคะแนนการเปลี่ยนเลย์เอาต์เพิ่มขึ้นเมื่อผู้ใช้ใช้คุณสมบัติการขยายภาพ
ในการตรวจสอบว่าการเปลี่ยนเลย์เอาต์เกิดขึ้นขณะวางเมาส์บนรูปภาพหรือไม่ เราใช้ข้อมูลโค้ดด้านล่างจาก https://web.dev/cls/ ซึ่งเพิ่ม console.log
เมื่อเลย์เอาต์เกิดขึ้น:
let cls = 0; new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { if (!entry.hadRecentInput) { cls += entry.value; console.log('Current CLS value:', cls, entry); } }}).observe({type: 'layout-shift', buffered: true});
ในการตรวจสอบเพิ่มเติม เราพบว่า ASDA ประสบปัญหาที่คล้ายกันและได้นำ Chrome มาใช้
สาเหตุ
ในหน้ารายละเอียดสินค้า ผู้ใช้สามารถเลื่อนเมาส์ไปบนภาพผลิตภัณฑ์เพื่อดูส่วนที่ขยายของภาพเคียงข้างกับภาพผลิตภัณฑ์จริง เนื่องจากวิดีโอนี้แสดงให้เห็นว่าเรากำลังพูดถึงอะไร
คุณลักษณะการขยายภาพช่วยให้ผู้ใช้ของเราได้รูปลักษณ์และความรู้สึกของผลิตภัณฑ์ รวมทั้งช่วยให้มั่นใจได้ว่าเป็นผลิตภัณฑ์รุ่นที่ต้องการซื้อ
เราใช้ไลบรารีการ react-image zoom
เพื่อสร้างฟังก์ชันการขยายรูปภาพนี้
ไลบรารี Image Magnify มักจะมีเลนส์ (สี่เหลี่ยมที่เคลื่อนที่เมื่อเมาส์เคลื่อนที่ภายในภาพ) เนื่องจากเลนส์นี้เปลี่ยนตำแหน่งบนและซ้ายด้วยการเคลื่อนไหวของเมาส์ จึงถูกตรวจพบว่าเป็นการเลื่อนเลย์เอาต์ที่ทริกเกอร์ CLS เราตรวจสอบหน้าห้องสมุดรวมถึงไลบรารีการโต้ตอบที่คล้ายกันอื่น ๆ ( react-image-magnify
, react-image-zoom
, react-image-magnifiers
) และพบว่าทั้งหมดนั้นประสบปัญหา CLS เดียวกัน
เราแก้ไขมันอย่างไร
เราสังเกตว่า react-image-zoom
กำลังใช้ไลบรารี js-image-zoom
ดังนั้นเราจึงต้องแก้ไขไลบรารี js-image zoom
เพื่อแก้ไขปัญหา
การแก้ปัญหาค่อนข้างตรงไปตรงมา ขณะที่เลื่อนเมาส์ไปที่ภาพผลิตภัณฑ์ ชิ้นเลนส์ภาพจะเคลื่อนที่โดยการเปลี่ยนตำแหน่งด้านซ้ายและด้านบน ในการแก้ไขปัญหา เราใช้ transform translate
ซึ่งย้ายองค์ประกอบไปยังเลเยอร์ใหม่ กล่าวคือ การเคลื่อนไหวใดๆ ที่เกิดขึ้นบนเลเยอร์ใหม่นี้จะไม่ทำให้เกิดการเปลี่ยนเลย์เอาต์อีกต่อไป:
ฉันได้สร้าง PR ให้กับ repo ดั้งเดิมด้วย เพื่อให้นักพัฒนารายอื่นที่ใช้ไลบรารี่นี้สามารถกำจัดปัญหา CLS ได้
ผลกระทบของการเปลี่ยนแปลง
หลังจากปรับใช้โค้ดกับการใช้งานจริง CLS ได้รับการแก้ไขในหน้ารายละเอียดผลิตภัณฑ์ และจำนวนหน้าที่ได้รับผลกระทบจาก CLS ลดลง 98%:
เนื่องจากเราใช้ transform
จึงช่วยให้ภาพขยายประสบการณ์ที่ราบรื่นยิ่งขึ้นให้กับผู้ใช้
หมายเหตุ : Paul Irish ได้เขียนบทความที่ยอดเยี่ยมในหัวข้อนี้
การเปลี่ยนแปลงที่สำคัญอื่นๆ ที่เราทำเพื่อ CLS
นอกจากนี้ยังมีปัญหาอื่นๆ ที่เราเผชิญผ่านหน้าต่างๆ ในเว็บไซต์ของเราซึ่งมีส่วนทำให้เกิด CLS มาดูองค์ประกอบและส่วนประกอบเหล่านั้นกัน และดูว่าเราพยายามลดการเปลี่ยนแปลงของเลย์เอาต์ที่เกิดขึ้นอย่างไร
เว็บฟอนต์:
เราสังเกตเห็นว่าการโหลดแบบอักษรล่าช้าทำให้ผู้ใช้รู้สึกหงุดหงิดเนื่องจากเนื้อหากะพริบและยังทำให้เกิดการเปลี่ยนเลย์เอาต์บางส่วน เพื่อลดสิ่งนี้ เราได้ทำการเปลี่ยนแปลงเล็กน้อย:- เราได้โฮสต์ฟอนต์เองแทนที่จะโหลดจาก CDN บุคคลที่สาม
- เราโหลดแบบอักษรไว้ล่วงหน้า
- เราใช้ตัวเลือกการแสดงแบบอักษร
รูปภาพ:
ค่าความสูงหรือความกว้างที่หายไปในรูปภาพทำให้องค์ประกอบหลังจากรูปภาพเปลี่ยนไปเมื่อโหลดรูปภาพแล้ว สิ่งนี้กลายเป็นผู้สนับสนุนหลักให้กับ CLS เนื่องจากเราใช้ Next.js เราจึงใช้ประโยชน์จากองค์ประกอบภาพในตัวที่เรียกว่าnext/images
องค์ประกอบนี้รวมแนวทางปฏิบัติที่ดีที่สุดเกี่ยวกับรูปภาพหลายประการ มันถูกสร้างขึ้นบนแท็ก HTML<img>
และสามารถช่วยปรับปรุง LCP และ CLS ฉันขอแนะนำเป็นอย่างยิ่งให้อ่าน RFC นี้เพื่อค้นหาคุณสมบัติหลักและข้อดีของการใช้งานเลื่อนไม่มีที่สิ้นสุด:
บนเว็บไซต์ของเรา หน้ารายการผลิตภัณฑ์มีการเลื่อนแบบไม่รู้จบ ดังนั้น ในขั้นแรก เมื่อผู้ใช้เลื่อนไปที่ด้านล่างของหน้า พวกเขาเห็นส่วนท้ายเป็นเวลาเสี้ยววินาทีก่อนที่จะโหลดชุดข้อมูลชุดถัดไป จะทำให้เค้าโครงเปลี่ยนไป เพื่อแก้ปัญหานี้ เราได้ดำเนินการไม่กี่ขั้นตอน:- เราเรียก API เพื่อโหลดข้อมูลก่อนที่ผู้ใช้จะไปถึงด้านล่างสุดของรายการ
- เราได้จองพื้นที่เพียงพอสำหรับสถานะการโหลด และเราจะแสดงโครงร่างผลิตภัณฑ์ระหว่างสถานะการโหลด ดังนั้นเมื่อผู้ใช้เลื่อนดู พวกเขาไม่เห็นส่วนท้ายเป็นเวลาเสี้ยววินาทีขณะกำลังโหลดผลิตภัณฑ์
Addy Osmani ได้เขียนบทความโดยละเอียดเกี่ยวกับแนวทางนี้ ซึ่งผมขอแนะนำให้ตรวจสอบเป็นอย่างยิ่ง
ประเด็นที่สำคัญ
- แม้ว่า Lighthouse และ WebpageTest จะช่วยในการค้นหาปัญหาด้านประสิทธิภาพที่เกิดขึ้นจนถึงการโหลดหน้า แต่ไม่สามารถตรวจพบปัญหาด้านประสิทธิภาพหลังจากการโหลดหน้าเว็บ
- ส่วนขยาย Web Vitals สามารถตรวจพบการเปลี่ยนแปลง CLS ที่เกิดจากการโต้ตอบของผู้ใช้ ดังนั้นหากหน้ามีค่า CLS สูง แต่ Lighthouse หรือ WebpageTest รายงาน CLS ต่ำ ส่วนขยาย Web Vitals สามารถช่วยระบุปัญหาได้
- ข้อมูล Google Search Console อิงตามข้อมูลของผู้ใช้จริง จึงสามารถชี้ให้เห็นถึงปัญหาด้านประสิทธิภาพที่อาจเกิดขึ้น ณ จุดใดก็ได้ในวงจรชีวิตของหน้าเว็บ เมื่อตรวจพบและแก้ไขปัญหาแล้ว การตรวจสอบส่วนรายงานอีกครั้งสามารถช่วยตรวจสอบประสิทธิภาพของการแก้ไขประสิทธิภาพได้ การเปลี่ยนแปลงจะแสดงภายในไม่กี่วันในส่วนรายงาน Web Vitals
ความคิดสุดท้าย
แม้ว่าปัญหา CLS จะค่อนข้างยากต่อการดีบัก แต่การใช้เครื่องมือต่างๆ ร่วมกันจนถึงการโหลดหน้าเว็บ (Lighthouse, WebPageTest) และส่วนขยาย Web Vitals (หลังจากโหลดหน้าเว็บ) สามารถช่วยเราระบุปัญหาได้ นอกจากนี้ยังเป็นหนึ่งในตัวชี้วัดที่กำลังอยู่ระหว่างการพัฒนาจำนวนมากเพื่อให้ครอบคลุมสถานการณ์ต่างๆ ซึ่งหมายความว่าวิธีการวัดจะมีการเปลี่ยนแปลงในอนาคต เรากำลังติดตาม https://web.dev/evolving-cls/ เพื่อทราบเกี่ยวกับการเปลี่ยนแปลงที่จะเกิดขึ้น
สำหรับเรา เรากำลังดำเนินการปรับปรุง Core Web Vitals อื่นๆ อย่างต่อเนื่องเช่นกัน เมื่อเร็วๆ นี้ เราได้ปรับใช้การโหลดล่วงหน้าของรูปภาพที่ตอบสนอง และเริ่มให้บริการรูปภาพในรูปแบบ WebP ซึ่งช่วยให้เราลด 75% ของเพย์โหลดรูปภาพ ลด LCP ลง 62% และดัชนีความเร็ว 24% คุณสามารถอ่านรายละเอียดเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพสำหรับการปรับปรุง LCP และดัชนีความเร็ว หรือติดตามบล็อกด้านวิศวกรรมของเราเพื่อทราบเกี่ยวกับงานที่น่าตื่นเต้นอื่นๆ ที่เรากำลังดำเนินการอยู่
เราขอขอบคุณ Alex Castle ที่ช่วยเราดีบักปัญหา CLS ในหน้าผลิตภัณฑ์และแก้ไขปัญหาในการใช้งาน next/images