视频卡顿因默认同步预加载媒体文件阻塞首屏渲染;应设 preload="none"、移除 autoplay/loop,用 intersectionobserver 懒加载,并优化 poster 图片格式、尺寸与解码方式,同时确保 width/height 属性防止布局抖动。

为什么
因为默认行为是同步加载并预解析整个媒体文件,哪怕用户根本没点播放。浏览器会立刻发起请求、解码元数据、甚至缓冲前几秒——这对首屏渲染是毁灭性阻塞。
- 不加任何属性的
<video></video>会触发 preload="auto"(Chrome 默认),相当于告诉浏览器“把整个视频下完” - 即使设置了
preload="none",某些浏览器仍会下载 poster 图片并解析容器尺寸,造成 layout shift -
<audio></audio>在移动端常被静音策略拦截,但加载逻辑照旧,白占带宽
怎么让
核心是切断「自动加载」与「自动播放」的默认链路,把控制权交还给用户或滚动位置。
- 强制设置
preload="none",禁用任何预加载行为 - 移除
autoplay和loop属性,避免策略冲突 - 用
loading="lazy"(仅对<img>原生支持,<video></video>不生效,别信文档里过时说法) - 真正可靠的懒加载:监听
IntersectionObserver,进入视口后再动态设置src或调用load()
示例:
<video controls width="640" height="360" preload="none"><source type="video/mp4"></source></video>
JS 中触发:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const video = entry.target;
const source = video.querySelector('source');
source.src = source.dataset.src;
video.load(); // 手动触发加载
observer.unobserve(video);
}
});
});
WebP/AVIF 对视频没用,但 poster 图必须优化
poster 属性指定的封面图是首个渲染节点,它直接参与关键渲染路径。一张未压缩的 2MB JPG 就能让 LCP 延迟 2 秒以上。
- poster 必须用 WebP(支持透明、体积小)或 AVIF(更小,但需降级 fallback)
- 尺寸严格匹配
width/height属性,避免重排;建议用object-fit: cover控制裁剪 - 添加
decoding="async"属性,让浏览器用后台线程解码,不阻塞主线程 - 不要用 base64 内联 poster——base64 编码膨胀 ~33%,且无法被 CDN 缓存
自托管 vs CDN 视频资源的取舍陷阱
CDN 能降低延迟,但对大体积视频反而可能拖慢——因为 CDN 边缘节点未必缓存完整文件,回源耗时不可控;而自托管配合 range 请求 + HTTP/2 多路复用,更适合流式场景。
- 确认服务器支持
Accept-Ranges: bytes响应头,否则 seek 操作会失败 - 若用 CDN,务必开启「视频分片缓存」策略(如 Cloudflare Stream、AWS CloudFront 的 partial cache),而非默认全量缓存
- 对小于 5MB 的短视频(如 banner 动效),可考虑转为 GIF → WebP 动画 → 或直接用 CSS animation 替代,彻底规避
<video></video>
最易被忽略的一点:所有 <video></video> 都该有明确的 width 和 height,否则浏览器无法预留空间,导致布局抖动(layout shift),影响 CLS 分数。这个属性不是可选的“样式建议”,而是渲染性能刚需。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











