เผยแพร่: 16 สิงหาคม 2019
คุณอาจต้องทำการโหลดวิดีโอแบบ Lazy Load ด้วยเช่นเดียวกับองค์ประกอบรูปภาพ โดยทั่วไปวิดีโอจะโหลดด้วยองค์ประกอบ <video>
แต่สำหรับวิดีโอที่โฮสต์ในบริการอื่นๆ เช่น YouTube วิดีโอเหล่านั้นอาจใช้ <iframe>
(ในกรณีนี้ โปรดดูบทความเกี่ยวกับ iframe แบบการโหลดแบบเลื่อน)
วิธีโหลด <video>
แบบเลื่อนเวลาจะขึ้นอยู่กับกรณีการใช้งาน เนื่องจากมีโซลูชันที่แตกต่างกัน 2-3 รายการ
สำหรับวิดีโอที่ไม่เล่นอัตโนมัติ
โดยทั่วไปแล้ว แนวทางปฏิบัติแนะนำคือการหลีกเลี่ยงวิดีโอที่เล่นอัตโนมัติเนื่องจากจะปล่อยให้ผู้ใช้เป็นผู้ควบคุม ในกรณีเหล่านี้ การระบุแอตทริบิวต์ preload
ในองค์ประกอบ <video>
เป็นวิธีที่ดีที่สุดในการหลีกเลี่ยงการโหลดวิดีโอทั้งเรื่อง
<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
ตัวอย่างก่อนหน้านี้ใช้แอตทริบิวต์ preload
ที่มีค่า none
เพื่อไม่ให้เบราว์เซอร์โหลดข้อมูลวิดีโอใดๆ ล่วงหน้า แอตทริบิวต์ poster
จะให้ตัวยึดตําแหน่งแก่องค์ประกอบ <video>
ซึ่งจะแสดงในพื้นที่นั้นขณะที่วิดีโอโหลด
ในเบราว์เซอร์ส่วนใหญ่ preload
จะตั้งค่าเริ่มต้นเป็น metadata
และระบบจะโหลดวิดีโอบางส่วนไว้ล่วงหน้าโดยใช้ส่วนหัว Content-Range
ซึ่งอาจส่งผลให้มีการดาวน์โหลดข้อมูลมากกว่าที่ต้องการ โดยเฉพาะในกรณีที่เบราว์เซอร์ไม่รองรับส่วนหัว Content-Range
แม้ว่าจะรองรับแล้ว แต่เบราว์เซอร์จะไม่ทราบตำแหน่งไบต์ที่จัดเก็บข้อมูลเมตา และข้อมูลเมตาอาจไม่ได้จัดเก็บไว้ที่ส่วนต้นของไฟล์ ดังนั้น วิธีที่ดีที่สุดในการหลีกเลี่ยงการโหลดวิดีโอคือการระบุ none
และใช้ preload="none"
การดำเนินการนี้สามารถปรับปรุงเพิ่มเติมเพื่อโหลดข้อมูลเมตาล่วงหน้าเมื่อผู้ใช้วางเมาส์เหนือวิดีโอด้วยแอตทริบิวต์ onmouseenter
(หรือด้วยตัวแฮนเดิลเหตุการณ์ mouseenter
ที่เทียบเท่า)
<video controls
preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
วิธีนี้ไม่เพียงช่วยลดความล่าช้าเมื่อผู้ใช้เล่นวิดีโอเท่านั้น แต่ยังแสดงระยะเวลาของวิดีโอทันทีที่ผู้ใช้เปิดวิดีโอ
วิดีโอสามารถมีคุณสมบัติเป็นผู้สมัคร LCP รูปภาพ poster
จะโหลดเร็วกว่าวิดีโอ ดังนั้นคุณควรใช้รูปภาพโปสเตอร์ในกรณีที่รูปภาพเป็น LCP ที่เป็นไปได้ แต่ก็ต้องโหลดรูปภาพล่วงหน้าด้วยค่าแอตทริบิวต์ fetchpriority
เป็น "high"
ดังนี้
<link rel="preload" href="one-does-not-simply-placeholder.jpg" as="image" fetchpriority="high">
<video controls preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
สําหรับวิดีโอที่ทำหน้าที่แทน GIF แบบเคลื่อนไหว
วิดีโอที่เล่นอัตโนมัติมักใช้กับภาพเคลื่อนไหวแบบรวดเร็วสไตล์ GIF แม้ว่า GIF แบบเคลื่อนไหวจะได้รับความนิยมอย่างแพร่หลาย แต่ก็ยังด้อยกว่าวิดีโอที่เทียบเท่าในหลายๆ ด้าน โดยเฉพาะเรื่องขนาดไฟล์ GIF แบบเคลื่อนไหวอาจมีข้อมูลขนาดหลายเมกะไบต์ วิดีโอที่มีคุณภาพภาพใกล้เคียงกันมักจะมีขนาดเล็กกว่ามาก
การใช้องค์ประกอบ <video>
แทน GIF ที่เป็นภาพเคลื่อนไหวนั้นไม่ตรงไปตรงมาเท่ากับองค์ประกอบ <img>
GIF แบบเคลื่อนไหวมีลักษณะ 3 อย่างดังนี้
- วิดีโอจะเล่นโดยอัตโนมัติเมื่อโหลด
- โดยเล่นวนไปเรื่อยๆ (แต่ก็อาจไม่เสมอไป)
- วิดีโอไม่มีแทร็กเสียง
การทำเช่นนี้ด้วยองค์ประกอบ <video>
จะมีลักษณะดังนี้
<video autoplay muted loop playsinline>
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
แอตทริบิวต์ autoplay
, muted
และ loop
นั้นเข้าใจได้ทันที playsinline
เป็นสิ่งจําเป็นเพื่อให้การเล่นอัตโนมัติเกิดขึ้นใน iOS ตอนนี้คุณมีวิดีโอที่เปลี่ยนเป็น GIF ที่ใช้งานได้แล้ว ซึ่งใช้ได้กับทุกแพลตฟอร์ม แต่การโหลดแบบ Lazy Loading นั้นทำอย่างไร ในการเริ่มต้น ให้แก้ไขมาร์กอัป <video>
ดังนี้
<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
<source data-src="one-does-not-simply.webm" type="video/webm">
<source data-src="one-does-not-simply.mp4" type="video/mp4">
</video>
คุณจะเห็นการเพิ่มแอตทริบิวต์ poster
ซึ่งให้คุณระบุตัวยึดตําแหน่งเพื่อใช้พื้นที่ขององค์ประกอบ <video>
จนกว่าระบบจะโหลดวิดีโอแบบ Lazy Load เช่นเดียวกับตัวอย่างการโหลดแบบเลื่อนเวลาของ <img>
ให้เก็บ URL ของวิดีโอไว้ในแอตทริบิวต์ data-src
ขององค์ประกอบ <source>
แต่ละรายการ จากนั้นใช้โค้ด JavaScript ที่คล้ายกับตัวอย่างการโหลดแบบเลื่อนเวลาของภาพโดย Intersection Observer ดังนี้
document.addEventListener("DOMContentLoaded", function() {
var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));
if ("IntersectionObserver" in window) {
var lazyVideoObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(video) {
if (video.isIntersecting) {
for (var source in video.target.children) {
var videoSource = video.target.children[source];
if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
videoSource.src = videoSource.dataset.src;
}
}
video.target.load();
video.target.classList.remove("lazy");
lazyVideoObserver.unobserve(video.target);
}
});
});
lazyVideos.forEach(function(lazyVideo) {
lazyVideoObserver.observe(lazyVideo);
});
}
});
เมื่อทำการโหลดแบบเลื่อนเวลาขององค์ประกอบ <video>
คุณจะต้องวนดูองค์ประกอบย่อย <source>
ทั้งหมดและเปลี่ยนแอตทริบิวต์ data-src
เป็นแอตทริบิวต์ src
เมื่อดำเนินการเสร็จแล้ว คุณต้องเรียกใช้การโหลดวิดีโอโดยเรียกใช้เมธอด load
ขององค์ประกอบ จากนั้นสื่อจะเริ่มเล่นโดยอัตโนมัติตามแอตทริบิวต์ autoplay
เมื่อใช้วิธีนี้ คุณจะมีโซลูชันวิดีโอที่จำลองลักษณะการทำงานของ GIF แบบเคลื่อนไหว แต่ไม่ต้องใช้อินเทอร์เน็ตมากเท่ากับ GIF แบบเคลื่อนไหว และคุณจะโหลดเนื้อหาแบบ Lazy Load ได้
ไลบรารีการโหลดแบบ Lazy Loading
ไลบรารีต่อไปนี้จะช่วยคุณในการโหลดวิดีโอแบบ Lazy Load
- vanilla-lazyload และ lozad.js เป็นตัวเลือกที่มีน้ำหนักเบามากซึ่งใช้ Intersection Observer เท่านั้น ด้วยเหตุนี้ ไลบรารีจึงมีประสิทธิภาพสูง แต่จะต้องใส่ Polyfill ก่อนจึงจะใช้ในเบราว์เซอร์รุ่นเก่าได้
- yall.js เป็นไลบรารีที่ใช้ Intersection Observer และเปลี่ยนไปใช้ Event Handler นอกจากนี้ยังสามารถโหลดรูปภาพ
poster
ของวิดีโอแบบ Lazy Load โดยใช้แอตทริบิวต์data-poster
ได้ด้วย - หากต้องการใช้ไลบรารีการโหลดแบบเลื่อนเวลาเฉพาะ React คุณอาจพิจารณาใช้ react-lazyload แม้ว่าจะไม่ได้ใช้ Intersection Observer แต่ IntersectionObserver มีวิธีการโหลดรูปภาพแบบ Lazy Loading ที่คุ้นเคยสำหรับผู้ที่คุ้นเคยกับการพัฒนาแอปพลิเคชันด้วย React
ไลบรารีการโหลดแบบเลื่อนดูทีละรายการเหล่านี้มีเอกสารประกอบที่ชัดเจนพร้อมรูปแบบมาร์กอัปมากมายสำหรับการโหลดแบบเลื่อนดู