การแก้ปัญหา CLS ในเว็บไซต์อีคอมเมิร์ซ Next.js-Powered (กรณีศึกษา)

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ การเปลี่ยนเค้าโครงสะสมเป็นหนึ่งในเว็บหลักที่ยากที่สุดซึ่งจำเป็นต่อการดีบัก ในบทความนี้ เราจะพูดถึงเครื่องมือต่างๆ เพื่อตรวจสอบ CLS เมื่อใดควรใช้ (และเมื่อไม่ใช้) และวิธีแก้ไขปัญหา CLS บางอย่างที่เราเผชิญในเว็บไซต์อีคอมเมิร์ซที่ใช้ Next.js

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

มีตัวบ่งชี้ประสิทธิภาพหลัก (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 ซึ่งค่อนข้างต่ำ

CLS คือ .004
CLS แสดงผล CLS ต่ำที่ . .004 (ตัวอย่างขนาดใหญ่)

หน้ารายงาน Lighthouse มีส่วนการวินิจฉัย ซึ่งยังไม่แสดงองค์ประกอบใด ๆ ที่ทำให้เกิดค่า CLS สูง

หน้ารายงานประภาคาร
การแสดงตัวอย่างหน้ารายงานรวมทั้งผลการบริจาค 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 ซึ่งย้ายองค์ประกอบไปยังเลเยอร์ใหม่ กล่าวคือ การเคลื่อนไหวใดๆ ที่เกิดขึ้นบนเลเยอร์ใหม่นี้จะไม่ทำให้เกิดการเปลี่ยนเลย์เอาต์อีกต่อไป:

จัดการการเคลื่อนไหวของเลนส์โดยใช้ transform translate
(ตัวอย่างขนาดใหญ่)

ฉันได้สร้าง PR ให้กับ repo ดั้งเดิมด้วย เพื่อให้นักพัฒนารายอื่นที่ใช้ไลบรารี่นี้สามารถกำจัดปัญหา CLS ได้

การสร้าง PR ไปยัง repo เดิม
PR สร้างขึ้นเพื่อช่วยกำจัดปัญหา CLS (ตัวอย่างขนาดใหญ่)

ผลกระทบของการเปลี่ยนแปลง

หลังจากปรับใช้โค้ดกับการใช้งานจริง CLS ได้รับการแก้ไขในหน้ารายละเอียดผลิตภัณฑ์ และจำนวนหน้าที่ได้รับผลกระทบจาก CLS ลดลง 98%:

กราฟิกที่แสดงผลกระทบของการเปลี่ยนแปลง
transform มีข้อได้เปรียบด้านประสิทธิภาพเหนือการจัดการตำแหน่งโดยใช้ด้านซ้ายและด้านบน (ตัวอย่างขนาดใหญ่)

เนื่องจากเราใช้ 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