ที่ผ่านมา การตรวจสอบว่าเนื้อหาหลักของหน้าเว็บโหลดขึ้นและปรากฏต่อผู้ใช้นั้นเป็นเรื่องที่ท้าทายสำหรับนักพัฒนาเว็บ เมตริกเก่าๆ เช่น load หรือ DOMContentLoaded จะทำงานได้ไม่ดีเนื่องจากไม่ได้สอดคล้องกับสิ่งที่ผู้ใช้เห็นบนหน้าจอ และเมตริกประสิทธิภาพที่ใหม่กว่าซึ่งเน้นผู้ใช้เป็นหลัก เช่น First Contentful Paint (FCP) จะให้เห็นเพียงช่วงแรกของประสบการณ์การโหลดเท่านั้น หากหน้าเว็บแสดงหน้าจอแนะนำหรือแสดงสัญญาณบอกสถานะการโหลด ช่วงเวลานี้ไม่เกี่ยวข้องกับผู้ใช้มากนัก
ที่ผ่านมา เราขอแนะนำให้ใช้เมตริกประสิทธิภาพ เช่น First Meaningful Paint (FMP) และดัชนีความเร็ว (SI) (ทั้งคู่มีใน Lighthouse) เพื่อช่วยบันทึกประสบการณ์การโหลดเพิ่มเติมหลังจากการลงสีครั้งแรก แต่เมตริกเหล่านี้มีความซับซ้อน อธิบายได้ยาก และมักไม่ถูกต้อง ซึ่งหมายความว่าจะไม่สามารถระบุได้เมื่อเนื้อหาหลักของหน้าโหลดขึ้นมาแล้ว
จากการพูดคุยของคณะทำงานด้านประสิทธิภาพเว็บของ W3C และการวิจัยของ Google พบว่าวิธีที่แม่นยำมากขึ้นในการวัดเมื่อเนื้อหาหลักของหน้าโหลดขึ้นมาคือการดูเมื่อมีการแสดงองค์ประกอบที่ใหญ่ที่สุด
LCP คืออะไร
LCP รายงานเวลาแสดงผลของบล็อกรูปภาพหรือบล็อกที่ใหญ่ที่สุดซึ่งมองเห็นได้ในวิวพอร์ต เมื่อเทียบกับเวลาที่ผู้ใช้ไปยังส่วนต่างๆ ของหน้าเว็บเป็นครั้งแรก
คะแนน LCP ที่ดีเป็นอย่างไร
เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดี เว็บไซต์ควรพยายามใช้ Largest Contentful Paint ไม่เกิน 2.5 วินาที เกณฑ์ที่ดีในการวัดคือเปอร์เซ็นไทล์ที่ 75 ของการโหลดหน้าเว็บที่แบ่งกลุ่มระหว่างอุปกรณ์เคลื่อนที่และเดสก์ท็อป เพื่อให้มั่นใจว่าคุณจะบรรลุเป้าหมายนี้สำหรับผู้ใช้ส่วนใหญ่
องค์ประกอบใดบ้างที่นำมาพิจารณา
ตามที่ระบุไว้ใน Largest Contentful Paint ในปัจจุบัน API ประเภทองค์ประกอบ สิ่งที่พิจารณาสำหรับ Largest Contentful Paint มีดังนี้
- องค์ประกอบ
<img>
(เวลานำเสนอเฟรมแรกใช้สำหรับเนื้อหาที่เป็นภาพเคลื่อนไหว เช่น GIF หรือ PNG แบบเคลื่อนไหว) - องค์ประกอบ
<image>
ภายในองค์ประกอบ<svg>
- องค์ประกอบ
<video>
(เวลาที่ใช้ในการโหลดรูปภาพโปสเตอร์หรือเวลาที่ใช้ในการนำเสนอเฟรมแรกสำหรับวิดีโอ ขึ้นอยู่กับว่าเหตุการณ์ใดเกิดขึ้นก่อน) - องค์ประกอบที่มีภาพพื้นหลังซึ่งโหลดด้วยฟังก์ชัน
url()
(ตรงข้ามกับการไล่ระดับสี CSS) - องค์ประกอบระดับการบล็อกที่มีโหนดข้อความหรือองค์ประกอบข้อความย่อยอื่นๆ ระดับอินไลน์
โปรดทราบว่าการที่มีการจำกัดองค์ประกอบให้อยู่ในชุดแบบจำกัดนี้เราตั้งใจไว้เพื่อให้ทุกอย่างเรียบง่ายในช่วงแรก อาจมีการเพิ่มองค์ประกอบอื่นๆ (เช่น การรองรับ <svg>
อย่างเต็มรูปแบบ) ในอนาคตเมื่อมีการค้นคว้าวิจัยมากขึ้น
นอกจากการพิจารณาองค์ประกอบบางอย่างเท่านั้นแล้ว การวัดผล LCP ยังใช้วิธีการเรียนรู้เพื่อยกเว้นองค์ประกอบบางอย่างที่ผู้ใช้มีแนวโน้มจะเห็นว่า "ไม่ใช่เนื้อหาเต็ม" ด้วย สำหรับเบราว์เซอร์แบบ Chromium ได้แก่
- องค์ประกอบที่มีความทึบแสงเป็น 0 ที่ผู้ใช้มองไม่เห็น
- องค์ประกอบที่ครอบคลุมวิวพอร์ตทั้งหมด ซึ่งอาจถือว่าเป็นพื้นหลังแทนที่จะเป็นเนื้อหา
- รูปภาพที่มีตัวยึดตำแหน่งหรือรูปภาพอื่นๆ ที่มีเอนโทรปีต่ำ ซึ่งอาจไม่สอดคล้องกับเนื้อหาที่แท้จริงของหน้าเว็บ
เบราว์เซอร์มีแนวโน้มที่จะปรับปรุงวิธีการเหล่านี้อย่างต่อเนื่องเพื่อให้แน่ใจว่าเราตรงกับความคาดหวังของผู้ใช้เกี่ยวกับองค์ประกอบ contentful ที่ใหญ่ที่สุด
"เนื้อหา" เหล่านี้ การเรียนรู้อาจแตกต่างจากวิธีที่ First Contentful Paint (FCP) ใช้ ซึ่งอาจพิจารณาองค์ประกอบเหล่านี้บางอย่าง เช่น รูปภาพตัวยึดตำแหน่งหรือรูปภาพวิวพอร์ตแบบเต็ม แม้ว่าจะไม่มีสิทธิ์เป็นตัวเลือก LCP ก็ตาม แม้ว่าทั้งคู่จะใช้คำว่า "contentful" เป้าหมายของเมตริกเหล่านี้จะแตกต่างกันไป FCP จะวัดเมื่อมีการแสดงเนื้อหาในหน้าจอและ LCP เมื่อแสดงผลเนื้อหาหลักเพื่อให้ LCP มีความเฉพาะเจาะจงมากขึ้น
มีวิธีพิจารณาขนาดขององค์ประกอบอย่างไร
ปกติแล้วขนาดขององค์ประกอบที่รายงานสำหรับ LCP จะเป็นขนาดที่ผู้ใช้มองเห็นได้ภายในวิวพอร์ต หากองค์ประกอบขยายออกนอกวิวพอร์ต หรือหากองค์ประกอบหนึ่งถูกตัดออกหรือมีส่วนเกินที่มองไม่เห็น ส่วนเหล่านั้นจะไม่นับรวมในขนาดขององค์ประกอบ
สำหรับองค์ประกอบรูปภาพที่มีการปรับขนาดจากขนาดภายใน ขนาดที่รายงานจะเป็นขนาดที่มองเห็นได้หรือขนาดภายใน แล้วแต่ว่าขนาดใดจะเล็กกว่า
สำหรับองค์ประกอบข้อความ LCP จะพิจารณาเฉพาะสี่เหลี่ยมผืนผ้าเล็กที่สุดที่มีโหนดข้อความทั้งหมดได้
สำหรับองค์ประกอบทั้งหมด LCP จะไม่พิจารณาระยะขอบ ระยะห่างจากขอบ หรือเส้นขอบที่ใช้โดยใช้ CSS
จะมีการรายงาน LCP เมื่อใด
หน้าเว็บต่างๆ มักจะโหลดขึ้นเป็นช่วงๆ และผลที่ตามมาคืออาจเกิดจากองค์ประกอบที่มีขนาดใหญ่ที่สุดบนหน้าเว็บอาจมีการเปลี่ยนแปลง
ในการรับมือกับศักยภาพของการเปลี่ยนแปลงนี้ เบราว์เซอร์จะส่ง PerformanceEntry
ประเภท largest-contentful-paint
เพื่อระบุองค์ประกอบที่มีเนื้อหาขนาดใหญ่ที่สุดทันทีที่เบราว์เซอร์ลงสีเฟรมแรก แต่หลังจากแสดงผลเฟรมต่อมาแล้ว ระบบจะส่ง PerformanceEntry
อีกรายการหนึ่งทุกครั้งที่องค์ประกอบเนื้อหาขนาดใหญ่ที่สุดมีการเปลี่ยนแปลง
เช่น ในหน้าที่มีข้อความและรูปภาพหลัก เบราว์เซอร์อาจแสดงผลข้อความในตอนแรก ซึ่งถึงจุดนั้นเบราว์เซอร์จะส่งรายการ largest-contentful-paint
ซึ่งมีพร็อพเพอร์ตี้ element
ที่น่าจะอ้างอิง <p>
หรือ <h1>
หลังจากนั้น เมื่อรูปภาพหลักโหลดเสร็จแล้ว ระบบจะส่งรายการ largest-contentful-paint
รายการที่ 2 และพร็อพเพอร์ตี้ element
จะอ้างอิง <img>
องค์ประกอบหนึ่งๆ จะถือเป็นองค์ประกอบที่มีเนื้อหาขนาดใหญ่ที่สุดหลังจากที่แสดงผลและแสดงต่อผู้ใช้แล้วเท่านั้น รูปภาพที่ยังไม่ได้โหลดจะไม่ถือว่าเป็น "แสดงผล" โหนดข้อความที่ใช้แบบอักษรสำหรับเว็บในช่วงช่วงบล็อกแบบอักษรก็เช่นกัน ในกรณีเช่นนี้ ระบบอาจรายงานองค์ประกอบที่เล็กกว่าว่าเป็นองค์ประกอบที่มีเนื้อหาขนาดใหญ่ที่สุด แต่ทันทีที่องค์ประกอบที่ใหญ่กว่าแสดงผลเสร็จแล้ว ระบบจะสร้าง PerformanceEntry
ขึ้นอีกรายการ
นอกจากรูปภาพและแบบอักษรที่โหลดล่าช้าแล้ว หน้าเว็บอาจเพิ่มองค์ประกอบใหม่ลงใน DOM เมื่อมีเนื้อหาใหม่พร้อมให้บริการ หากองค์ประกอบใหม่เหล่านี้มีขนาดใหญ่กว่าองค์ประกอบที่มีเนื้อหาขนาดใหญ่ที่สุดก่อนหน้านี้ จะมีการรายงาน PerformanceEntry
ใหม่ด้วย
หากมีการนำองค์ประกอบที่มีเนื้อหาขนาดใหญ่ที่สุดออกจากวิวพอร์ตหรือแม้แต่ออกจาก DOM องค์ประกอบดังกล่าวจะยังคงเป็นองค์ประกอบที่มีเนื้อหาขนาดใหญ่ที่สุดเว้นแต่ว่าจะมีการแสดงผลองค์ประกอบที่ใหญ่กว่า
เบราว์เซอร์จะหยุดรายงานรายการใหม่ทันทีที่ผู้ใช้โต้ตอบกับหน้าเว็บ (ผ่านการแตะ เลื่อน หรือกดแป้น) เนื่องจากการโต้ตอบของผู้ใช้มักเปลี่ยนแปลงสิ่งที่ผู้ใช้มองเห็นได้ (โดยเฉพาะอย่างยิ่งเมื่อเลื่อน)
เพื่อทำการวิเคราะห์ คุณควรรายงาน PerformanceEntry
ที่ส่งล่าสุดไปยังบริการวิเคราะห์เท่านั้น
เวลาที่ใช้ในการโหลดเทียบกับเวลาในการแสดงผล
เพื่อความปลอดภัย การประทับเวลาในการแสดงผลรูปภาพจะไม่แสดงสำหรับรูปภาพแบบข้ามต้นทางที่ไม่มีส่วนหัว Timing-Allow-Origin
แต่จะแสดงเฉพาะเวลาที่ใช้ในการโหลดเท่านั้น (เนื่องจากมีการแสดงผ่าน API ของเว็บอื่นๆ จำนวนมากอยู่แล้ว)
จึงอาจทำให้เกิดสถานการณ์ที่ดูเป็นไปไม่ได้ซึ่ง API ของเว็บจะรายงาน LCP เร็วกว่า FCP ซึ่งจะไม่เป็นเช่นนี้ แต่ปรากฏขึ้นเนื่องจากข้อจำกัดด้านความปลอดภัยนี้เท่านั้น
หากทำได้ เราแนะนำให้ตั้งค่าส่วนหัว Timing-Allow-Origin
เสมอเพื่อให้เมตริกแม่นยำมากขึ้น
มีการจัดการการเปลี่ยนแปลงเลย์เอาต์และขนาดขององค์ประกอบอย่างไร
การเปลี่ยนแปลงขนาดหรือตำแหน่งขององค์ประกอบจะไม่สร้างตัวเลือก LCP ใหม่ๆ เพื่อลดค่าใช้จ่ายด้านประสิทธิภาพในการคำนวณและจัดส่งรายการใหม่ๆ ให้ต่ำ ระบบจะพิจารณาเฉพาะขนาดและตำแหน่งเริ่มต้นขององค์ประกอบในวิวพอร์ตเท่านั้น
ซึ่งหมายความว่าอาจไม่มีการรายงานรูปภาพที่แสดงผลนอกหน้าจอก่อนแล้วค่อยเปลี่ยนบนหน้าจอ นอกจากนี้ยังหมายความว่าองค์ประกอบที่แสดงผลครั้งแรกในวิวพอร์ตที่ถูกเลื่อนลง และอยู่นอกมุมมองจะยังคงรายงานขนาดเริ่มต้นในวิวพอร์ตอยู่
ตัวอย่าง
ต่อไปนี้คือตัวอย่างบางส่วนของกรณีที่ Largest Contentful Paint เกิดขึ้นในเว็บไซต์ยอดนิยมบางเว็บไซต์
![ไทม์ไลน์ Largest Contentful Paint จาก cnn.com](https://web.dev/static/articles/lcp/image/largest-contentful-paint-fc43128e011aa.png?authuser=5&hl=th)
![ไทม์ไลน์ Largest Contentful Paint จาก techcrunch.com](https://web.dev/static/articles/lcp/image/largest-contentful-paint-3713e2f14970a.png?authuser=5&hl=th)
ในทั้ง 2 ลำดับเวลาข้างต้น องค์ประกอบที่ใหญ่ที่สุดจะเปลี่ยนไปเมื่อเนื้อหาโหลด ในตัวอย่างแรก ระบบจะเพิ่มเนื้อหาใหม่ลงใน DOM และเปลี่ยนองค์ประกอบที่ใหญ่ที่สุด ในตัวอย่างที่ 2 การเปลี่ยนแปลงเลย์เอาต์และเนื้อหาที่เคยมีขนาดใหญ่ที่สุดจะถูกนำออกจากวิวพอร์ต
ซึ่งมักเป็นกรณีที่เนื้อหาที่โหลดล่าช้าจะมีขนาดใหญ่กว่าเนื้อหาที่อยู่ในหน้าอยู่แล้ว แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไป ตัวอย่าง 2 รายการถัดไปแสดง LCP ที่เกิดขึ้นก่อนโหลดหน้าเว็บเสร็จสมบูรณ์
![ไทม์ไลน์ Largest Contentful Paint จาก instagram.com](https://web.dev/static/articles/lcp/image/largest-contentful-paint-9bc403e812154.png?authuser=5&hl=th)
![ไทม์ไลน์ Largest Contentful Paint จาก google.com](https://web.dev/static/articles/lcp/image/largest-contentful-paint-6c5554de0eac7.png?authuser=5&hl=th)
ในตัวอย่างแรก โลโก้ของ Instagram จะโหลดเร็วมากและยังคงเป็นองค์ประกอบที่ใหญ่ที่สุดแม้จะมีเนื้อหาอื่นๆ แสดงอยู่เรื่อยๆ ในตัวอย่างหน้าผลการค้นหาของ Google Search องค์ประกอบที่ใหญ่ที่สุดคือย่อหน้าของข้อความที่แสดงก่อนที่รูปภาพหรือโลโก้ใดๆ จะโหลดเสร็จสิ้น เนื่องจากภาพทั้งหมดมีขนาดเล็กกว่าย่อหน้านี้ ภาพจึงยังคงเป็นองค์ประกอบที่ใหญ่ที่สุดตลอดกระบวนการโหลด
วิธีวัด LCP
คุณวัด LCP ได้ในห้องปฏิบัติการหรือในภาคสนาม และพร้อมให้ใช้งานในเครื่องมือต่อไปนี้
เครื่องมือภาคสนาม
- รายงานประสบการณ์ของผู้ใช้ Chrome
- PageSpeed Insights
- Search Console (รายงาน Core Web Vitals)
- ไลบรารี JavaScript
web-vitals
รายการ
เครื่องมือในห้องทดลอง
วัด LCP ใน JavaScript
หากต้องการวัด LCP ใน JavaScript ให้ใช้ Largest Contentful Paint API ตัวอย่างต่อไปนี้แสดงวิธีสร้าง PerformanceObserver
ที่รอฟังรายการ largest-contentful-paint
และบันทึกลงในคอนโซล
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
ในตัวอย่างข้างต้น รายการ largest-contentful-paint
ที่บันทึกไว้แต่ละรายการแสดงถึงตัวเลือก LCP ปัจจุบัน โดยทั่วไปแล้ว ค่า startTime
ของรายการสุดท้ายที่ปล่อยออกมาคือค่า LCP อย่างไรก็ตาม ก็อาจไม่ได้เป็นเช่นนั้นเสมอไป รายการ largest-contentful-paint
บางรายการไม่สามารถใช้วัด LCP ได้
ส่วนต่อไปนี้แสดงความแตกต่างระหว่างรายงาน API และวิธีคำนวณเมตริก
ความแตกต่างระหว่างเมตริกกับ API
- API จะส่งรายการ
largest-contentful-paint
รายการสำหรับหน้าที่โหลดในแท็บพื้นหลัง แต่ระบบควรละเว้นหน้าเหล่านั้นเมื่อคำนวณ LCP - API จะส่งรายการ
largest-contentful-paint
รายการต่อไปหลังจากที่หน้าเว็บทำงานอยู่เบื้องหลังแล้ว แต่ระบบควรละเว้นรายการเหล่านั้นเมื่อคำนวณ LCP (อาจพิจารณาองค์ประกอบได้เฉพาะในกรณีที่หน้าเว็บทำงานอยู่เบื้องหน้าตลอดช่วงเวลา) - API ไม่รายงานรายการ
largest-contentful-paint
เมื่อมีการคืนค่าหน้าจากBack-Forward Cache แต่ควรวัด LCP ในกรณีเหล่านี้เนื่องจากผู้ใช้พบว่าเป็นการเข้าชมหน้าที่แตกต่างกัน - API ไม่พิจารณาองค์ประกอบภายใน iframe แต่เมตริกจะพิจารณาเนื่องจากเป็นส่วนหนึ่งของประสบการณ์ของผู้ใช้หน้าเว็บ ในหน้าที่มี LCP ใน iframe เช่น ภาพโปสเตอร์ในวิดีโอแบบฝัง ข้อมูลนี้จะแสดงให้เห็นความแตกต่างระหว่าง CrUX และ RUM คุณควรพิจารณา LCP เพื่อวัด LCP อย่างเหมาะสม เฟรมย่อยจะใช้ API เพื่อรายงานรายการ
largest-contentful-paint
ของตนไปยังเฟรมหลักเพื่อการรวมได้ - API จะวัด LCP จากการเริ่มการนำทาง แต่สำหรับหน้าที่แสดงผลล่วงหน้า ควรวัดจาก
activationStart
เนื่องจากที่สอดคล้องกับเวลา LCP ตามที่ผู้ใช้พบ
แทนที่จะจดจำความแตกต่างเล็กๆ น้อยๆ เหล่านี้ นักพัฒนาแอปสามารถใช้ไลบรารี JavaScript web-vitals
เพื่อวัด LCP ซึ่งจะจัดการความแตกต่างเหล่านี้ให้คุณ (หากทำได้ โปรดทราบว่าปัญหา iframe ไม่ครอบคลุม)
import {onLCP} from 'web-vitals';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
ดูตัวอย่างที่สมบูรณ์เกี่ยวกับวิธีวัด LCP ใน JavaScript ได้ในซอร์สโค้ดของ onLCP()
จะเกิดอะไรขึ้นหากองค์ประกอบที่ใหญ่ที่สุดไม่ใช่สิ่งสำคัญที่สุด
ในบางกรณี องค์ประกอบที่สำคัญที่สุด (หรือหลายองค์ประกอบ) ในหน้าเว็บไม่เหมือนกับองค์ประกอบที่ใหญ่ที่สุด และนักพัฒนาซอฟต์แวร์อาจสนใจที่จะวัดเวลาการแสดงผลขององค์ประกอบอื่นๆ เหล่านี้แทน ซึ่งทำได้โดยใช้ Element Timing API ตามที่อธิบายไว้ในบทความเกี่ยวกับเมตริกที่กําหนดเอง
วิธีปรับปรุง LCP
อ่านคู่มือฉบับเต็มเกี่ยวกับการเพิ่มประสิทธิภาพ LCP เพื่อแนะนำกระบวนการระบุช่วงเวลาของ LCP ในภาคสนามและการใช้ข้อมูลในห้องทดลองเพื่อเจาะลึกและเพิ่มประสิทธิภาพ
แหล่งข้อมูลเพิ่มเติม
บันทึกการเปลี่ยนแปลง
บางครั้งอาจพบข้อบกพร่องใน API ที่ใช้ในการวัดเมตริก และบางครั้งอาจพบข้อบกพร่องในคำจำกัดความของเมตริกเอง ด้วยเหตุนี้ บางครั้งจึงอาจต้องมีการเปลี่ยนแปลง และการเปลี่ยนแปลงเหล่านี้อาจแสดงเป็นการปรับปรุงหรือความถดถอยในรายงานภายในและแดชบอร์ดของคุณ
การเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นกับการใช้งานหรือคำจำกัดความของเมตริกเหล่านี้จะปรากฏในบันทึกการเปลี่ยนแปลงนี้เพื่อช่วยคุณจัดการเรื่องนี้
หากมีความคิดเห็นเกี่ยวกับเมตริกเหล่านี้ ให้ระบุในกลุ่ม Google Web-vitals-feedback