ที่ผ่านมา เว็บนักพัฒนาซอฟต์แวร์ต้องพบกับความท้าทายในการวัดความเร็วที่เนื้อหาหลักของหน้าเว็บโหลดและแสดงต่อผู้ใช้ เมตริกเก่าๆ เช่น 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 มีดังนี้ตามที่ระบุไว้ใน Largest Contentful Paint API ในปัจจุบัน
- องค์ประกอบ
<img>
(เวลาแสดงเฟรมแรกใช้สำหรับเนื้อหาภาพเคลื่อนไหว เช่น GIF หรือ PNG แบบเคลื่อนไหว) - องค์ประกอบ
<image>
ภายในองค์ประกอบ<svg>
- องค์ประกอบ
<video>
(ระบบจะใช้เวลาในการโหลดภาพโปสเตอร์หรือเวลาแสดงเฟรมแรกสำหรับวิดีโอ ขึ้นอยู่กับว่าเวลาใดมาก่อน) - องค์ประกอบที่มีภาพพื้นหลังที่โหลดโดยใช้ฟังก์ชัน
url()
(ไม่ใช่การไล่สี CSS) - องค์ประกอบระดับบล็อกที่มีโหนดข้อความหรือองค์ประกอบข้อความระดับอินไลน์อื่นๆ
โปรดทราบว่าการจํากัดองค์ประกอบไว้เพียงชุดนี้เป็นการจงใจเพื่อให้ทุกอย่างเรียบง่ายตั้งแต่เริ่มต้น อาจมีการเพิ่มองค์ประกอบอื่นๆ (เช่น การรองรับ <svg>
อย่างเต็มรูปแบบ) ในอนาคตเมื่อมีการวิจัยเพิ่มเติม
นอกจากพิจารณาเฉพาะองค์ประกอบบางอย่างแล้ว การวัด LCP ยังใช้วิธีการหาค่าประมาณเพื่อยกเว้นองค์ประกอบบางอย่างที่ผู้ใช้มีแนวโน้มจะเห็นว่า "ไม่ใช่เนื้อหา" สำหรับเบราว์เซอร์ที่ใช้ Chromium รายการดังกล่าว ได้แก่
- องค์ประกอบที่มีความทึบแสง 0 ซึ่งผู้ใช้มองไม่เห็น
- องค์ประกอบที่ครอบคลุมวิวพอร์ตทั้งหน้าจอ ซึ่งมีแนวโน้มที่ระบบจะถือว่าเป็นส่วนหนึ่งของพื้นหลังมากกว่าเนื้อหา
- รูปภาพที่มีตัวยึดตำแหน่งหรือรูปภาพอื่นๆ ที่มีเอนโทรปีต่ำ ซึ่งอาจไม่สอดคล้องกับเนื้อหาที่แท้จริงของหน้าเว็บ
เบราว์เซอร์มีแนวโน้มที่จะปรับปรุงวิธีการเหล่านี้อย่างต่อเนื่องเพื่อให้แน่ใจว่าเราตรงกับความคาดหวังของผู้ใช้เกี่ยวกับองค์ประกอบ contentful ที่ใหญ่ที่สุด
การประเมินแบบ "มีเนื้อหา" เหล่านี้อาจแตกต่างจากการประเมินที่ใช้โดย First Contentful Paint (FCP) ซึ่งอาจพิจารณาองค์ประกอบเหล่านี้บางส่วน เช่น รูปภาพตัวยึดตำแหน่งหรือรูปภาพวิวพอร์ตแบบเต็ม แม้ว่าจะไม่มีสิทธิ์เป็น LCP ก็ตาม แม้ว่าทั้ง 2 รายการจะใช้คำว่า "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 อื่นๆ หลายรายการอยู่แล้ว)
ซึ่งอาจทําให้เกิดสถานการณ์ที่ดูเหมือนจะเป็นไปไม่ได้เมื่อ Web API รายงาน LCP เร็วกว่า FCP แต่เป็นเพียงข้อจำกัดด้านความปลอดภัยเท่านั้น
เราขอแนะนําให้ตั้งค่าส่วนหัว Timing-Allow-Origin
เสมอเมื่อเป็นไปได้ เพื่อให้เมตริกแม่นยํายิ่งขึ้น
มีการจัดการการเปลี่ยนแปลงเลย์เอาต์และขนาดขององค์ประกอบอย่างไร
การเปลี่ยนแปลงขนาดหรือตําแหน่งขององค์ประกอบจะไม่สร้างผู้สมัคร LCP ใหม่ เพื่อลดค่าใช้จ่ายเพิ่มเติมด้านประสิทธิภาพในการคำนวณและส่งรายการประสิทธิภาพใหม่ ระบบจะพิจารณาเฉพาะขนาดและตําแหน่งเริ่มต้นขององค์ประกอบในวิวพอร์ตเท่านั้น
ซึ่งหมายความว่าอาจไม่มีการรายงานรูปภาพที่แสดงผลนอกหน้าจอก่อนแล้วค่อยเปลี่ยนบนหน้าจอ และยังหมายความว่าองค์ประกอบที่แสดงผลในวิวพอร์ตตั้งแต่แรกซึ่งถูกดันลงจนมองไม่เห็นจะยังคงรายงานขนาดในวิวพอร์ตเริ่มต้น
ตัวอย่าง
ต่อไปนี้คือตัวอย่างเวลาที่ Largest Contentful Paint เกิดขึ้นในเว็บไซต์ยอดนิยมบางแห่ง
ในไทม์ไลน์ทั้ง 2 รายการด้านบน องค์ประกอบที่ใหญ่ที่สุดจะเปลี่ยนแปลงไปเมื่อโหลดเนื้อหา ในตัวอย่างแรก มีการเพิ่มเนื้อหาใหม่ลงใน DOM ซึ่งจะเปลี่ยนองค์ประกอบที่ใหญ่ที่สุด ในตัวอย่างที่ 2 การเปลี่ยนแปลงเลย์เอาต์และเนื้อหาที่เคยมีขนาดใหญ่ที่สุดจะถูกนำออกจากวิวพอร์ต
ซึ่งมักเป็นกรณีที่เนื้อหาที่โหลดช้าจะมีขนาดใหญ่กว่าเนื้อหาที่อยู่ในหน้าอยู่แล้ว แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไป ตัวอย่าง 2 รายการถัดไปแสดง LCP ที่เกิดขึ้นก่อนที่หน้าเว็บจะโหลดจนเสร็จ
ในตัวอย่างแรก โลโก้ Instagram จะโหลดค่อนข้างเร็วและยังคงเป็นองค์ประกอบที่ใหญ่ที่สุดแม้ว่าเนื้อหาอื่นๆ จะแสดงขึ้นทีละส่วนก็ตาม ในตัวอย่างหน้าผลการค้นหาของ Google Search องค์ประกอบที่ใหญ่ที่สุดคือย่อหน้าข้อความที่แสดงขึ้นก่อนที่รูปภาพหรือโลโก้จะโหลดเสร็จ เนื่องจากภาพทั้งหมดมีขนาดเล็กกว่าย่อหน้านี้ ภาพจึงยังคงเป็นองค์ประกอบที่ใหญ่ที่สุดตลอดกระบวนการโหลด
วิธีวัด 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
เมื่อมีการกู้คืนหน้าเว็บจากแคชย้อนกลับ/ไปข้างหน้า แต่ควรวัด LCP ในกรณีเหล่านี้เนื่องจากผู้ใช้จะเห็นว่าเป็นการเข้าชมหน้าเว็บที่แตกต่างกัน - API ไม่พิจารณาองค์ประกอบภายใน iframe แต่เมตริกจะพิจารณาเนื่องจากเป็นส่วนหนึ่งของประสบการณ์ของผู้ใช้หน้าเว็บ ในหน้าที่มี LCP ใน iframe เช่น ภาพโปสเตอร์ในวิดีโอแบบฝัง ข้อมูลนี้จะแสดงให้เห็นความแตกต่างระหว่าง CrUX และ RUM คุณควรพิจารณา LCP เพื่อวัด LCP อย่างเหมาะสม เฟรมย่อยสามารถใช้ API เพื่อรายงานรายการ
largest-contentful-paint
ไปยังเฟรมหลักเพื่อรวบรวมข้อมูล - API จะวัด LCP จากจุดเริ่มต้นของการนําทาง แต่สําหรับหน้าเว็บที่แสดงผลล่วงหน้า ควรวัด LCP จาก
activationStart
เนื่องจากเวลาดังกล่าวสอดคล้องกับเวลา LCP ที่ผู้ใช้ได้รับ
นักพัฒนาซอฟต์แวร์สามารถใช้web-vitals
ไลบรารี JavaScript เพื่อวัด 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