一、最简单但有效:preload="none"
<video controls preload="none" poster="cover.jpg"><source src="demo.mp4" type="video/mp4">
</video>
特点
-
❌ 页面加载时 不下载视频
-
✅ 点击播放才请求
-
👍 零 JS
-
👎 滚动到可视区不会自动加载
👉 适合:用户主动点播放的场景
二、推荐方案:IntersectionObserver 懒加载(通用)
HTML(不直接给 src)
<videoclass="lazy-video"controlsmutedplaysinlineposter="cover.jpg"src="demo.mp4">
</video>
JS
<script>
const videos = document.querySelectorAll('.lazy-video')const observer = new IntersectionObserver(entries => {entries.forEach(entry => {if (entry.isIntersecting) {const video = entry.targetvideo.src = video.dataset.srcvideo.load() // 开始加载observer.unobserve(video)}})
}, {rootMargin: '100px' // 提前加载
})videos.forEach(v => observer.observe(v))
</script>
优点
-
👍 真正“滚动到才加载”
-
👍 可控提前量
-
👍 静态页面最佳实践
三、自动播放视频懒加载(常见于官网)
⚠️ 浏览器限制:必须 muted 才能自动播放
<videoclass="lazy-video"mutedautoplayloopplaysinlineposter="cover.jpg"src="bg.mp4">
</video>
if (entry.isIntersecting) {video.src = video.dataset.srcvideo.play().catch(() => {})
}
📌 常用于:
-
首页背景视频
-
产品展示动效
四、多 source 视频(兼容格式)
<video class="lazy-video" poster="cover.jpg"><source src="demo.mp4" type="video/mp4"><source src="demo.webm" type="video/webm">
</video>
video.querySelectorAll('source').forEach(s => {s.src = s.dataset.src
})
video.load()
五、离开视口自动暂停(加分项)
const observer = new IntersectionObserver(entries => {entries.forEach(entry => {const video = entry.targetif (entry.isIntersecting) {video.play().catch(()=>{})} else {video.pause()}})
})
👉 对 长页面多个视频 非常重要