โหลดรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ไว้ล่วงหน้า

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

ภาพรวมของรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 78.
  • Safari: 17.2.

Source

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

รูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ ช่วยให้เบราว์เซอร์ดึงข้อมูลแหล่งที่มาของรูปภาพต่างๆ สำหรับอุปกรณ์ต่างๆ ได้ หากไม่ได้ใช้ CDN รูปภาพ ให้บันทึกรูปภาพแต่ละรูปในหลายมิติและระบุในแอตทริบิวต์ srcset ค่า w จะบอกความกว้างของแต่ละเวอร์ชันให้เบราว์เซอร์ทราบ เพื่อให้เบราว์เซอร์เลือกเวอร์ชันที่เหมาะสมสำหรับอุปกรณ์ใดก็ได้

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

ภาพรวมการโหลดล่วงหน้า

Browser Support

  • Chrome: 50.
  • Edge: 79.
  • Firefox: 85.
  • Safari: 11.1.

Source

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

<link rel="preload" as="image" href="important.png">

imagesrcset และ imagesizes

องค์ประกอบ <link> ใช้แอตทริบิวต์ imagesrcset และ imagesizes เพื่อโหลดรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ล่วงหน้า ใช้ร่วมกับ <link rel="preload"> โดยใช้ไวยากรณ์ srcset และ sizes ในองค์ประกอบ <img>

ตัวอย่างเช่น หากต้องการโหลดรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ซึ่งระบุด้วย

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

โดยเพิ่มข้อความต่อไปนี้ลงใน <head> ของ HTML

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">

ซึ่งจะเริ่มต้นคำขอโดยใช้ตรรกะการเลือกทรัพยากรเดียวกันกับที่ srcset และ sizes ใช้

กรณีการใช้งาน

กรณีการใช้งานการโหลดล่วงหน้าของรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์มีดังนี้

โหลดล่วงหน้าสำหรับรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ซึ่งแทรกแบบไดนามิก

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

คุณตรวจสอบปัญหานี้ในเว็บไซต์ที่มีแกลเลอรีรูปภาพที่โหลดแบบไดนามิกได้โดยทำดังนี้

  1. เปิดการสาธิตสไลด์โชว์นี้ ในแท็บใหม่
  2. กด Control+Shift+J (หรือ Command+Option+J บน Mac) เพื่อเปิด DevTools
  3. คลิกแท็บเครือข่าย
  4. ในรายการแบบเลื่อนลงการจำกัดอัตรา ให้เลือก 3G เร็ว
  5. ยกเลิกการเลือกช่องทำเครื่องหมายปิดใช้แคช
  6. โหลดหน้าเว็บซ้ำ
แผงเครือข่ายของ Chrome DevTools แสดงน้ำตกที่มีทรัพยากร JPEG ซึ่งเริ่มดาวน์โหลดหลังจาก JavaScript บางรายการเท่านั้น
หากไม่มีการโหลดล่วงหน้า รูปภาพจะเริ่มโหลดหลังจากที่เบราว์เซอร์เรียกใช้สคริปต์เสร็จแล้ว สำหรับรูปภาพแรกนั้นไม่จำเป็นต้องหน่วงเวลา

การใช้ preload ที่นี่จะช่วยให้รูปภาพเริ่มโหลดล่วงหน้าได้ จึงพร้อมแสดงเมื่อเบราว์เซอร์ต้องการแสดง

แผงเครือข่ายของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แสดงวอเตอร์ฟอลล์ที่มีทรัพยากร JPEG ซึ่งดาวน์โหลดควบคู่ไปกับ JavaScript บางรายการ
การโหลดรูปภาพแรกไว้ล่วงหน้าจะช่วยให้รูปภาพเริ่มโหลดพร้อมกับสคริปต์ได้

หากต้องการดูความแตกต่างที่การโหลดล่วงหน้าสร้างขึ้น ให้ตรวจสอบแกลเลอรีรูปภาพเดียวกันที่โหลดแบบไดนามิก แต่โหลดรูปภาพแรกไว้ล่วงหน้า โดยทำตามขั้นตอนจากตัวอย่างแรก

โหลดภาพพื้นหลังล่วงหน้าโดยใช้ image-set

หากมีรูปภาพพื้นหลังที่แตกต่างกันสำหรับความหนาแน่นของหน้าจอที่แตกต่างกัน คุณสามารถ ระบุรูปภาพเหล่านั้นใน CSS ด้วยไวยากรณ์ image-set ได้ จากนั้นเบราว์เซอร์จะ เลือกแสดงรูปภาพใดรูปภาพหนึ่งตาม DPR ของหน้าจอ

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

ปัญหาเกี่ยวกับรูปภาพพื้นหลัง CSS คือเบราว์เซอร์จะค้นพบรูปภาพเหล่านั้นหลังจากที่ดาวน์โหลดและประมวลผล CSS ทั้งหมดใน <head> ของหน้าเว็บแล้วเท่านั้น

คุณตรวจสอบปัญหานี้ได้ในเว็บไซต์ตัวอย่างที่มีรูปภาพพื้นหลังที่ปรับตามอุปกรณ์

แผงเครือข่ายของ Chrome DevTools แสดง Waterfall ที่มีทรัพยากร JPEG ซึ่งเริ่มดาวน์โหลดหลังจาก CSS บางรายการเท่านั้น
ในตัวอย่างนี้ การดาวน์โหลดรูปภาพจะไม่เริ่มจนกว่าจะดาวน์โหลด CSS เสร็จสมบูรณ์ ซึ่งทำให้การแสดงรูปภาพเกิดความล่าช้าโดยไม่จำเป็น

การโหลดรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ล่วงหน้าช่วยให้คุณโหลดรูปภาพเหล่านั้นได้เร็วขึ้น

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x">

การละเว้นแอตทริบิวต์ href จะช่วยให้มั่นใจได้ว่าเบราว์เซอร์ที่ไม่รองรับ imagesrcset ในองค์ประกอบ <link> แต่รองรับ image-set ใน CSS จะดาวน์โหลดแหล่งที่มาที่ถูกต้อง อย่างไรก็ตาม ผู้ใช้จะไม่ได้รับประโยชน์จากการโหลดล่วงหน้าในกรณีนี้

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

แผงเครือข่ายของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แสดงลำดับการดาวน์โหลดทรัพยากร JPEG พร้อมกับ CSS บางรายการ
ในกรณีนี้ รูปภาพและ CSS จะเริ่มดาวน์โหลดพร้อมกัน ทำให้รูปภาพโหลดได้เร็วขึ้น

ผลลัพธ์ที่ได้จากการโหลดรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ล่วงหน้า

การโหลดรูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ล่วงหน้าอาจช่วยให้รูปภาพแสดงเร็วขึ้นในทางทฤษฎี แต่ในทางปฏิบัติจะเป็นอย่างไร

เพื่อตอบคำถามนี้ ฉันจึงสร้างสำเนาร้านค้า PWA สาธิต 2 รายการ รายการหนึ่งที่ไม่ได้โหลดรูปภาพล่วงหน้า และอีกรายการหนึ่งที่โหลดรูปภาพบางส่วนล่วงหน้า เนื่องจากเว็บไซต์โหลดรูปภาพแบบ Lazy Loading โดยใช้ JavaScript จึงมีแนวโน้มที่จะได้รับประโยชน์จากการ โหลดล่วงหน้าสำหรับรูปภาพที่ปรากฏในวิวพอร์ตเริ่มต้น

ซึ่งให้ผลลัพธ์ต่อไปนี้สำหรับ ไม่มีการโหลดล่วงหน้า และสำหรับการโหลดรูปภาพล่วงหน้า

  • Start Render ยังคงเหมือนเดิม
  • ดัชนีความเร็ว ดีขึ้นเล็กน้อย (273 มิลลิวินาที เนื่องจากรูปภาพมาถึงเร็วขึ้นจึงไม่กินพื้นที่ พิกเซลมากนัก)
  • Last Painted Hero ดีขึ้นอย่างมากถึง 1.2 วินาที
การเปรียบเทียบแถบฟิล์มของ WebPageTest แสดงให้เห็นว่ารูปภาพที่โหลดล่วงหน้าจะแสดงเร็วกว่าประมาณ 1.5 วินาที
รูปภาพจะโหลดเร็วขึ้นอย่างมากเมื่อโหลดล่วงหน้า ซึ่งจะช่วยปรับปรุงประสบการณ์ของผู้ใช้ได้เป็นอย่างดี

โหลดล่วงหน้าและ <picture>

คณะทำงานด้านประสิทธิภาพของเว็บกำลังหารือเกี่ยวกับการเพิ่มการโหลดล่วงหน้าเทียบเท่าสำหรับ srcset และ sizes แต่ไม่ใช่สำหรับองค์ประกอบ <picture> ซึ่งจัดการกรณีการใช้งาน "การกำกับศิลป์"

เรายังคงมีปัญหาทางเทคนิคที่ต้องแก้ไขสำหรับการโหลดล่วงหน้า <picture> แต่ในระหว่างนี้ คุณสามารถใช้วิธีแก้ปัญหาชั่วคราวได้ดังนี้

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

ตรรกะการเลือกแหล่งที่มารูปภาพขององค์ประกอบ <picture> จะพิจารณาแอตทริบิวต์ media ขององค์ประกอบ <source> ตามลำดับ ค้นหารายการแรกที่ ตรงกัน แล้วใช้ทรัพยากรที่แนบมา

เนื่องจากการโหลดล่วงหน้าแบบปรับตามพื้นที่โฆษณาไม่มีแนวคิดเรื่อง "ลำดับ" หรือ "รายการแรกที่ตรงกัน" คุณจึงต้อง แปลงจุดพักเป็นรูปแบบต่อไปนี้

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">

โหลดล่วงหน้าและ type

องค์ประกอบ <picture> ยังรองรับการจับคู่ใน type แรกด้วย เพื่อให้คุณ ระบุรูปแบบรูปภาพต่างๆ เพื่อให้เบราว์เซอร์เลือกรูปแบบรูปภาพแรก ที่รองรับได้ กรณีการใช้งานนี้ไม่รองรับการโหลดล่วงหน้า

สำหรับเว็บไซต์ที่ใช้การจับคู่ประเภท เราขอแนะนำให้หลีกเลี่ยงการโหลดล่วงหน้า และให้เครื่องสแกนการโหลดล่วงหน้าเลือกรูปภาพจากองค์ประกอบ <picture> และ <source> แทน ซึ่งเป็นแนวทางปฏิบัติแนะนำอยู่แล้ว โดยเฉพาะอย่างยิ่งเมื่อใช้ Fetch Priority เพื่อช่วยจัดลำดับความสำคัญ ของรูปภาพที่เหมาะสม

ผลกระทบต่อ Largest Contentful Paint (LCP)

เนื่องจากรูปภาพอาจเป็นองค์ประกอบที่อาจเป็น LCP การโหลดรูปภาพล่วงหน้าจึงช่วยปรับปรุง LCP ของเว็บไซต์ได้

ไม่ว่ารูปภาพที่คุณโหลดล่วงหน้าจะปรับตามอุปกรณ์หรือไม่ การโหลดล่วงหน้าจะทำงานได้ดีที่สุดเมื่อไม่พบทรัพยากรรูปภาพในเพย์โหลดมาร์กอัปเริ่มต้น นอกจากนี้ คุณยังได้รับการปรับปรุง LCP เพิ่มเติมในเว็บไซต์ที่แสดงผลมาร์กอัปฝั่งไคลเอ็นต์มากกว่าในเว็บไซต์ที่ส่งมาร์กอัปที่สมบูรณ์จากเซิร์ฟเวอร์