Lazy loading ส่งผลต่อ Largest Contentful Paint ของคุณจริง ๆ อย่างไร
Lazy loading มีประโยชน์ แต่ไม่ใช่วิธีแก้ประสิทธิภาพแบบครอบจักรวาล สำหรับ LCP มันอาจช่วย ทำให้แย่ลง หรือไม่ส่งผลเลย ขึ้นอยู่กับว่าทรัพยากรใดถูกเลื่อนออกไป
สารบัญ
- Lazy loading คือการตัดสินใจเรื่องการจัดคิว ไม่ใช่คาถาเพิ่มความเร็ว
- เบราว์เซอร์ทำอะไรเมื่อคุณ lazy load รูปภาพ
- กฎง่าย ๆ: อย่า lazy load ตัวเลือกที่เป็น LCP
- การแก้ไข: ใช้ URL ภายในที่ถูกต้องจริง ๆ
- เมื่อ lazy loading ช่วยปรับปรุง LCP ได้
- รูปแบบที่ดีกว่าสำหรับรูปภาพ LCP
- Background images ต้องใช้ความระมัดระวังเป็นพิเศษ
- JavaScript lazy loading มักทำให้แย่ลง
- LCP ไม่ได้เป็นปัญหารูปภาพเสมอไป
- วิธีทดสอบการเปลี่ยนแปลง lazy loading โดยไม่หลอกตัวเอง
- นโยบายที่ใช้ได้จริงสำหรับเว็บไซต์ส่วนใหญ่
Lazy loading คือการตัดสินใจเรื่องการจัดคิว ไม่ใช่คาถาเพิ่มความเร็ว
Lazy loading มักถูกอธิบายว่าเป็นการปรับปรุงประสิทธิภาพ ซึ่งก็จริงในแง่เดียวกับที่การไม่จัดกระเป๋าเดินทางช่วยลดน้ำหนัก มันช่วยเพราะเบราว์เซอร์ทำงานน้อยลงในช่วงแรก
ความแตกต่างนี้สำคัญสำหรับ Largest Contentful Paint ซึ่งมักย่อว่า LCP LCP วัดว่าองค์ประกอบที่มีความหมายและมีขนาดใหญ่ที่สุดใน viewport ถูกเรนเดอร์เมื่อใด ในหลายหน้า องค์ประกอบนั้นคือ hero image ในบางหน้า อาจเป็นหัวข้อขนาดใหญ่ poster image รูปสินค้า หรือบล็อกเนื้อหา
Lazy loading เปลี่ยนเวลาที่ทรัพยากรถูกเรียกขอ มันไม่ได้ทำให้รูปภาพ decode เร็วขึ้น ไม่ได้ทำให้เซิร์ฟเวอร์ตอบสนองเร็วขึ้น และไม่ได้ทำให้ฟอนต์เรนเดอร์เร็วขึ้น หากคุณ lazy load สิ่งที่ผิด โดยเฉพาะองค์ประกอบที่จะกลายเป็น LCP คุณกำลังบอกให้เบราว์เซอร์รอก่อนที่จะดึงสิ่งที่จำเป็นต้องแสดงเพื่อให้ผ่าน Core Web Vitals
นี่คือเหตุผลที่ lazy loading ถูกใช้มากเกินไป และถูกเข้าใจน้อยเกินไปในเวลาเดียวกัน
เบราว์เซอร์ทำอะไรเมื่อคุณ lazy load รูปภาพ
Native image lazy loading มักเพิ่มแบบนี้:
<img src='hero.jpg' loading='lazy' alt='...'>
เมื่อใช้ loading='lazy' เบราว์เซอร์ได้รับอนุญาตให้เลื่อนการดึงรูปภาพออกไปจนกว่าจะเชื่อว่ารูปนั้นน่าจะจำเป็นต้องใช้ ในทางปฏิบัติ เบราว์เซอร์ใช้ระยะห่างจาก viewport สภาพเครือข่าย ขนาดรูปภาพ และ heuristic อื่น ๆ กฎที่แน่นอนเป็นรายละเอียดของการใช้งานแต่ละเบราว์เซอร์และอาจเปลี่ยนได้
เมื่อใช้ loading='eager' หรือไม่มี lazy attribute ในกรณีส่วนใหญ่ เบราว์เซอร์จะถือว่ารูปภาพเป็นส่วนหนึ่งของกระบวนการโหลดตามปกติ มันยังต้องจัดลำดับความสำคัญระหว่าง CSS, JavaScript, ฟอนต์, รูปภาพ และ request อื่น ๆ แต่รูปภาพจะถูกค้นพบได้ทันที
นั่นหมายความว่า lazy loading ส่งผลหลัก ๆ ต่อสามช่วง:
- Discovery: เมื่อเบราว์เซอร์รับรู้ว่ามีทรัพยากรนั้น
- Request start: เมื่อการดึงข้อมูลผ่านเครือข่ายเริ่มขึ้น
- Render timing: เมื่อทรัพยากรถูก decode และ paint ได้ในที่สุด
สำหรับ LCP จุดที่อันตรายคือ request start หาก request ของรูปภาพ LCP เริ่มช้า ทุกอย่างหลังจากนั้นก็จะเลื่อนช้าตามไปด้วย
กฎง่าย ๆ: อย่า lazy load ตัวเลือกที่เป็น LCP
หากรูปภาพมองเห็นได้ใน viewport แรก และมีแนวโน้มจะเป็นองค์ประกอบ contentful ที่ใหญ่ที่สุด อย่า lazy load รูปนั้น
ซึ่งรวมถึง:
- hero images
- รูปสินค้าหลักที่อยู่ above the fold
- รูปนำบทความขนาดใหญ่
- รูปภาพลักษณะคล้าย background ขนาดใหญ่ที่ทำด้วย
<img> - video poster images เมื่อ poster เป็นองค์ประกอบภาพหลัก
เบราว์เซอร์ไม่สามารถเรนเดอร์รูปภาพ LCP ได้จนกว่ารูปนั้นจะถูกเรียกขอ ถ่ายโอน decode และ paint Lazy loading แทรกความไม่แน่นอนเข้ามาก่อนขั้นตอนแรก แม้ความล่าช้าเพียงเล็กน้อยก็อาจพอที่จะทำให้ LCP เปลี่ยนจากยอมรับได้เป็นแย่บนการเชื่อมต่อที่ช้ากว่า
รูปแบบความล้มเหลวที่พบบ่อยมีลักษณะดังนี้:
- เซิร์ฟเวอร์ส่ง HTML
- เบราว์เซอร์ parse รูปภาพที่อยู่ above-the-fold
- รูปภาพมี
loading='lazy' - เบราว์เซอร์รอ เพราะ heuristic ของ lazy-loading บอกว่าสามารถรอได้
- CSS และ JavaScript ยังคงโหลดต่อไป
- request ของรูปภาพเริ่มช้ากว่าที่ควร
- LCP มาช้า แม้ไฟล์รูปภาพเองจะถูก optimize อย่างสมเหตุสมผลแล้ว
เรื่องนี้น่าหงุดหงิดเพราะหน้าอาจดูเรียบร้อยในการ review โค้ด ปัญหาไม่ได้อยู่ที่ขนาดไฟล์เพียงอย่างเดียว แต่อยู่ที่ priority
หากคุณกำลังอ่านผลลัพธ์จาก lab และพยายามดูว่า LCP เป็นปัญหาจริงหรือไม่ คู่มือของเราเรื่องการอ่าน Lighthouse report โดยไม่ตื่นตระหนกตั้งใจให้ใช้งานได้จริง: แยก field data, lab hints และวิธีแก้ออกจากกันก่อนเริ่มแก้โค้ด (หมายเหตุ: หาก routing ของคุณ case-sensitive ให้ใช้ URL ที่ตรงจาก CMS ของคุณ)
การแก้ไข: ใช้ URL ภายในที่ถูกต้องจริง ๆ
URL บทความ Wux ที่ถูกต้องคือ วิธีอ่าน Lighthouse report โดยไม่ตื่นตระหนก ประเด็นยังเหมือนเดิม: ระบุองค์ประกอบ LCP ให้ได้ก่อนเปลี่ยนพฤติกรรมการโหลด
เมื่อ lazy loading ช่วยปรับปรุง LCP ได้
Lazy loading สามารถปรับปรุง LCP ได้ทางอ้อม เมื่อมันกันทรัพยากรที่ไม่สำคัญออกจากทางของเบราว์เซอร์
ลองนึกถึงหน้าสินค้าที่มี hero product image อยู่ด้านบน และมี carousel รูปสินค้าแนะนำสิบสองรูปอยู่ below the fold หากรูปทั้งสิบสามรูปโหลดแบบ eager ทั้งหมด เบราว์เซอร์อาจใช้ bandwidth และ connection slots กับรูปที่ผู้ใช้ยังมองไม่เห็น บนเครือข่ายที่จำกัด สิ่งนี้อาจแข่งขันกับ hero image, CSS หรือไฟล์ฟอนต์
การ lazy load รูปใน carousel ที่อยู่ below-fold อาจช่วยให้รูปภาพ LCP โหลดเร็วขึ้น เพราะมี request ที่ไม่สำคัญน้อยลงมาแข่งขันระหว่างการโหลดหน้าในช่วงแรก
นี่คือกรณีด้านประสิทธิภาพที่ถูกต้องของ lazy loading:
- eager load ตัวเลือก LCP ที่อยู่ above-the-fold
- lazy load รูปภาพที่อยู่ below the initial viewport
- หลีกเลี่ยง script หนัก ๆ ที่ inject รูปภาพสำคัญเข้ามาช้า
- ใส่ขนาดรูปภาพไว้ใน HTML เพื่อหลีกเลี่ยง layout shifts
Lazy loading ไม่ใช่การ optimize LCP โดยตัวมันเอง มันเป็นเครื่องมือจัดลำดับความสำคัญของทรัพยากร มันช่วยเมื่อปกป้อง critical path
รูปแบบที่ดีกว่าสำหรับรูปภาพ LCP
สำหรับรูปภาพ LCP ที่อยู่ above-the-fold เป้าหมายคือทำให้เบราว์เซอร์ค้นพบมันเร็ว เรียกขอมันเร็ว และเรนเดอร์ได้โดยไม่มีความไม่เสถียรของ layout
baseline ที่ดีมีลักษณะดังนี้:
<img
src='/images/product-hero.avif'
srcset='/images/product-hero-800.avif 800w, /images/product-hero-1400.avif 1400w'
sizes='(max-width: 768px) 100vw, 720px'
width='1400'
height='900'
loading='eager'
fetchpriority='high'
decoding='async'
alt='Black hiking backpack with roll-top closure'
>
ส่วนสำคัญเหล่านี้ไม่ใช่ของตกแต่ง:
loading='eager'ป้องกันความล่าช้าจาก lazy-loadingfetchpriority='high'บอกเบราว์เซอร์ว่ารูปนี้สำคัญwidthและheightจองพื้นที่และลด layout shiftsrcsetและsizesป้องกันการดาวน์โหลดไฟล์ที่ใหญ่เกินจำเป็น- format สมัยใหม่สามารถลดเวลา transfer ได้เมื่อใช้อย่างรอบคอบ
หากคุณยังส่ง JPEG ขนาดใหญ่ไฟล์เดียวให้ทุกหน้าจอ image format และ responsive sizing อาจสำคัญกว่า lazy-loading attribute สำหรับ decision tree ที่ใช้งานได้จริง ดู เมื่อ AVIF ดีกว่า WebP และเมื่อไม่ใช่
Background images ต้องใช้ความระมัดระวังเป็นพิเศษ
CSS background images ไม่ถูกค้นพบเร็วเท่ารูปภาพ HTML ปกติ เบราว์เซอร์ต้องดึงและ parse CSS ก่อนจึงจะรู้ว่ามีรูปเหล่านั้น หากองค์ประกอบ LCP ของคุณเป็น CSS background image คุณได้ทำให้ discovery ยากขึ้นแล้ว
ไม่ได้หมายความว่าห้ามใช้ background images แต่หมายความว่าคุณควรตั้งใจเลือกใช้
สำหรับรูปตกแต่ง CSS backgrounds ใช้ได้ดี สำหรับ hero imagery ที่มีความหมาย องค์ประกอบ <img> หรือ <picture> มักดีกว่า เพราะมองเห็นได้สำหรับ HTML parser, รองรับ alt text และทำงานได้ดีกับ responsive image attributes
หากคุณจำเป็นต้องใช้ CSS background สำหรับรูปภาพ LCP ให้พิจารณา preload รูปนั้น:
<link rel='preload' as='image' href='/images/hero.avif'>
Preload ก็ไม่ใช่ไม้กายสิทธิ์เช่นกัน การ preload รูปภาพมากเกินไปสร้างปัญหา priority แบบเดียวกันในเครื่องแต่งกายคนละชุด ใช้กับรูปเดียวที่สำคัญจริง ๆ ไม่ใช่กับทุกรูปใน design system
JavaScript lazy loading มักทำให้แย่ลง
ก่อนที่ native lazy loading จะรองรับอย่างแพร่หลาย หลายไซต์ใช้ JavaScript libraries ที่สลับ data-src เข้าไปใน src หลัง page load หรือหลัง intersection observer ทำงาน บางไซต์ยังทำเช่นนั้นอยู่
วิธีนี้อาจสมเหตุสมผลสำหรับหน้าบทความยาว ๆ หรือ gallery ที่มีรูปจำนวนมาก แต่เป็นตัวเลือกที่แย่สำหรับเนื้อหา above-the-fold
Browser preload scanner ทำงานเร็ว แต่มันไม่สามารถ request รูปภาพที่ URL ถูกซ่อนอยู่ใน custom attribute ได้จนกว่า JavaScript จะทำงาน หาก hero image ของคุณเริ่มต้นเป็น data-src='hero.jpg' คุณได้เลื่อน discovery ไปไว้หลัง script download, parsing, execution และ framework hydration
นี่เป็นการแลกเปลี่ยนที่ไม่ดีสำหรับ LCP ใส่ URL รูปภาพสำคัญไว้ใน HTML จริง ปล่อยให้เบราว์เซอร์ทำหน้าที่ของมัน
LCP ไม่ได้เป็นปัญหารูปภาพเสมอไป
ในบางหน้า องค์ประกอบ LCP คือข้อความ ในกรณีนั้น lazy loading รูปภาพอาจแทบไม่มีผลโดยตรง bottleneck ของคุณอาจเป็น render-blocking CSS, การตอบสนองของเซิร์ฟเวอร์ที่ช้า, client-side rendering หรือ web fonts
ฟอนต์ควรถูกกล่าวถึงเป็นพิเศษ เพราะเป็นสาเหตุที่ซ่อนอยู่บ่อยครั้งของการเรนเดอร์ข้อความที่มาช้า หัวข้อขนาดใหญ่สามารถกลายเป็น LCP ได้ และพฤติกรรมการโหลดฟอนต์อาจหน่วงหรือเปลี่ยนเวลาที่หัวข้อนั้น paint หากงานด้านรูปภาพของคุณไม่ขยับ metric ให้ตรวจสอบองค์ประกอบ LCP โดยตรง แทนที่จะเดา บทความของเราเรื่อง web fonts ในฐานะ performance win ครอบคลุมวิธีแก้ที่น่าเบื่อแต่ใช้ได้บ่อย: ลดจำนวน weights, ใช้ format สมัยใหม่, ตั้ง fallback อย่างสมเหตุสมผล
วิธีทดสอบการเปลี่ยนแปลง lazy loading โดยไม่หลอกตัวเอง
อย่าทดสอบด้วยการจ้องหน้าของคุณบน office Wi-Fi คุณต้องดู request timing
ใช้ workflow นี้:
- เปิด Chrome DevTools และ record Performance trace
- เปิดใช้ network throttling เช่น Fast 4G หรือ Slow 4G
- reload หน้าโดยปิด cache
- หา LCP marker
- ระบุองค์ประกอบ LCP
- ใน Network panel ตรวจสอบว่าทรัพยากรนั้นเริ่มโหลดเมื่อใด
หากทรัพยากร LCP เริ่มช้า ให้ถามว่าทำไม:
- มันถูก lazy loaded หรือไม่?
- มันถูก inject โดย JavaScript หรือไม่?
- มันถูกซ่อนอยู่ใน CSS หรือไม่?
- มันถูกลด priority ไปอยู่หลังรูปภาพอื่นหรือไม่?
- เซิร์ฟเวอร์ตอบสนองช้าหรือไม่?
จากนั้นเปลี่ยนอย่างเดียวแล้วทดสอบใหม่ งานด้าน performance จะยุ่งเหยิงเมื่อทีมเปลี่ยน image format, lazy loading, preloading, JavaScript bundles และ CDN settings ใน deployment เดียวกัน คุณอาจทำให้หน้าดีขึ้นได้ แต่จะไม่รู้ว่าการเปลี่ยนใดมีผลจริง
Field data ก็สำคัญเช่นกัน Lab tools มีประโยชน์สำหรับการวินิจฉัย แต่ LCP แปรผันตามอุปกรณ์ เครือข่าย viewport สถานะ cache และภูมิศาสตร์ ใช้ real-user monitoring หรือข้อมูล Chrome User Experience Report เมื่อทำได้
<!-- tool-cta:start -->
💡 ลองทำสิ่งนี้: รักษารูปภาพ LCP ของคุณให้มีขนาดเล็กและโหลดแบบมีลำดับความสำคัญโดยนำไปผ่าน Image Compressor เพื่อให้แสดงผลได้อย่างรวดเร็วโดยไม่ต้องใช้ lazy loading
<!-- tool-cta:end -->
นโยบายที่ใช้ได้จริงสำหรับเว็บไซต์ส่วนใหญ่
สำหรับ marketing sites, ecommerce pages, documentation sites และ publisher pages ส่วนใหญ่ นโยบายนี้เพียงพอ:
- รูปหลัก above-the-fold: eager load และพิจารณา high fetch priority
- รูปเนื้อหา below-the-fold: lazy load
- icons และ UI assets ขนาดเล็กมาก: โดยทั่วไปไม่คุ้มที่จะคิดแยกรายชิ้น
- CSS background hero: พิจารณาเปลี่ยนเป็น HTML image หรือ preload อย่างระมัดระวัง
- JavaScript-injected hero image: แก้ rendering architecture หากเป็นไปได้
- Carousels: eager load เฉพาะ slide แรกที่มองเห็น; lazy load ที่เหลือ
มี edge cases อยู่เสมอ Browser heuristics ดีขึ้น Frameworks เพิ่ม automatic image components บาง platforms ตอนนี้หลีกเลี่ยงการ lazy load รูปภาพที่ตรวจพบว่าอยู่ใกล้ viewport แล้ว อย่างไรก็ตาม หลักการไม่เปลี่ยน: ทรัพยากรสำคัญควรมาเร็วและเห็นชัด; ทรัพยากรที่ไม่สำคัญควรรอ
Lazy loading มีคุณค่าเมื่อมันสะท้อนความแตกต่างนั้น มันเป็นอันตรายเมื่อมันซ่อนเนื้อหาที่สำคัญที่สุดจากเบราว์เซอร์ จนกว่าหน้าจะเริ่มแพ้การแข่งขัน LCP ไปแล้ว