ที่ผ่านมา การตรวจสอบว่าเนื้อหาหลักของหน้าเว็บโหลดขึ้นและปรากฏต่อผู้ใช้นั้นเป็นเรื่องที่ท้าทายสำหรับนักพัฒนาเว็บ เมตริกเก่าๆ เช่น load หรือ DOMContentLoaded จะทำงานได้ไม่ดีเนื่องจากไม่ได้สอดคล้องกับสิ่งที่ผู้ใช้เห็นบนหน้าจอ และเมตริกประสิทธิภาพที่ใหม่กว่าซึ่งเน้นที่ผู้ใช้เป็นหลัก เช่น First Contentful Paint (FCP) จะจับภาพเฉพาะช่วงเริ่มต้นของประสบการณ์การโหลดเท่านั้น หากหน้าเว็บแสดงหน้าจอแนะนำหรือตัวบ่งชี้การโหลด ช่วงเวลานี้จะไม่เกี่ยวข้องกับผู้ใช้มากนัก
ที่ผ่านมาเราแนะนําเมตริกประสิทธิภาพ เช่น First Meaningful Paint (FMP) และดัชนีความเร็ว (SI) (ทั้ง 2 แบบมีให้ใช้งานใน 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
แต่ระบบจะแสดงเฉพาะเวลาในการโหลด (เนื่องจากข้อมูลนี้แสดงผ่าน Web API อื่นๆ หลายรายการอยู่แล้ว)
จึงอาจทำให้เกิดสถานการณ์ที่ดูเป็นไปไม่ได้ซึ่ง API ของเว็บจะรายงาน LCP เร็วกว่า FCP ซึ่งจะไม่เป็นเช่นนี้ แต่ปรากฏขึ้นเนื่องจากข้อจำกัดด้านความปลอดภัยนี้เท่านั้น
เราขอแนะนําให้ตั้งค่าส่วนหัว Timing-Allow-Origin
เสมอเมื่อเป็นไปได้ เพื่อให้เมตริกแม่นยํายิ่งขึ้น
มีการจัดการการเปลี่ยนแปลงเลย์เอาต์และขนาดองค์ประกอบอย่างไร
การเปลี่ยนแปลงขนาดหรือตําแหน่งขององค์ประกอบจะไม่สร้างผู้สมัคร LCP ใหม่ เพื่อลดค่าใช้จ่ายเพิ่มเติมด้านประสิทธิภาพในการคำนวณและส่งรายการประสิทธิภาพใหม่ ระบบจะพิจารณาเฉพาะขนาดและตำแหน่งเริ่มต้นขององค์ประกอบในวิวพอร์ตเท่านั้น
ซึ่งหมายความว่าระบบอาจไม่รายงานรูปภาพที่แสดงผลนอกหน้าจอในตอนแรกแล้วเปลี่ยนไปแสดงบนหน้าจอ และยังหมายความว่าองค์ประกอบที่แสดงผลในวิวพอร์ตตั้งแต่แรกซึ่งถูกดันลงจนมองไม่เห็นจะยังคงรายงานขนาดในวิวพอร์ตเริ่มต้น
ตัวอย่าง
ต่อไปนี้คือตัวอย่างเวลาที่ Largest Contentful Paint เกิดขึ้นในเว็บไซต์ยอดนิยมบางแห่ง
ในไทม์ไลน์ทั้ง 2 รายการด้านบน องค์ประกอบที่ใหญ่ที่สุดจะเปลี่ยนแปลงไปเมื่อโหลดเนื้อหา ในตัวอย่างแรก มีการเพิ่มเนื้อหาใหม่ลงใน DOM ซึ่งจะเปลี่ยนองค์ประกอบที่ใหญ่ที่สุด ในตัวอย่างที่ 2 การเปลี่ยนแปลงเลย์เอาต์และเนื้อหาที่เคยมีขนาดใหญ่ที่สุดจะถูกนำออกจากวิวพอร์ต
แม้ว่าเนื้อหาที่โหลดช้ามักจะมีขนาดใหญ่กว่าเนื้อหาที่มีอยู่ในหน้า แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไป ตัวอย่าง 2 รายการถัดไปแสดง LCP ที่เกิดขึ้นก่อนที่หน้าเว็บจะโหลดจนเสร็จ
ในตัวอย่างแรก โลโก้ของ Instagram จะโหลดเร็วมากและยังคงเป็นองค์ประกอบที่ใหญ่ที่สุดแม้จะมีเนื้อหาอื่นๆ แสดงอยู่เรื่อยๆ ในตัวอย่างหน้าผลการค้นหาของ Google Search องค์ประกอบที่ใหญ่ที่สุดคือย่อหน้าของข้อความที่แสดงก่อนที่รูปภาพหรือโลโก้ใดๆ จะโหลดเสร็จสิ้น เนื่องจากรูปภาพแต่ละรูปมีขนาดเล็กกว่าย่อหน้านี้ ย่อหน้าจึงยังคงเป็นองค์ประกอบที่ใหญ่ที่สุดตลอดกระบวนการโหลด
วิธีวัด LCP
LCP สามารถวัดได้ในห้องทดลองหรือในสนาม และเครื่องมือต่อไปนี้มี LCP
เครื่องมือภาคสนาม
- รายงานประสบการณ์ของผู้ใช้ Chrome
- PageSpeed Insights
- Search Console (รายงาน Core Web Vitals)
web-vitals
ไลบรารี JavaScript
เครื่องมือของห้องทดลอง
วัด 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 จากการเริ่มการนำทาง แต่สำหรับหน้าที่แสดงผลล่วงหน้า ควรวัด 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