preload 是浏览器预加载建议而非强制指令,iOS Safari 默认忽略所有 preload 值并降级为 none;最稳妥的是 preload="metadata",需服务端支持字节范围请求且视频经 faststart 优化。

preload 不是开关,是建议;浏览器可以、也经常忽略它——尤其在 iOS Safari 和多数移动端 WebView 中。
preload="metadata" 是最稳妥的默认值
它只请求视频文件头部(如 MP4 的 moov box),用于获取时长、宽高、封面帧、音轨列表等元信息,不下载画面帧或音频流。体积小(通常几 KB)、兼容性好、无带宽浪费。
- 务必确保服务端响应头含
Accept-Ranges: bytes,否则浏览器无法做字节范围请求,metadata模式可能退化为下载前几 KB 甚至整个文件 - 视频文件需经
ffmpeg -c copy -movflags +faststart重写,否则moov在文件末尾,浏览器必须下载全部才能解析元数据 - 配合
poster属性使用,能立刻显示占位图,避免白屏或闪烁 - 监听
loadedmetadata事件确认元信息就绪,不要依赖video.readyState判断是否“已预加载”
iOS Safari 无视 preload="auto" 是铁律
从 iOS 10 开始,Safari 将所有 preload 值(包括 auto)静默降级为 none,哪怕你写了也等于没写。这不是 bug,是苹果强制的流量与电池策略。
- 即使页面加了
autoplay,preload也会被直接忽略 -
video.readyState在 iOS 上长期卡在0(HAVE_NOTHING),直到用户点击播放才开始加载 - 不要试图用 UA 字符串检测 iOS 后再设
auto——写了也没用,不如省掉这行代码
动态改 preload 基本无效,真正起作用的是 load() + IntersectionObserver
静态 preload 属性只对初始 HTML 解析阶段生效。动态插入的 <video></video> 元素,即使设置 preload="auto",也不会触发预加载。
立即学习“前端免费学习笔记(深入)”;
- 想实现“即将进入视口时才加载”,应监听
IntersectionObserver,当目标可见后调用video.load() - 调用
load()后,需监听canplay或loadeddata才能安全展示控件或自动播放 - 若需更激进加载(如课程主视频),可搭配
<link rel="preload" as="video" href="xxx.mp4">主动发起请求(仅同域有效) - 注意:该
<link>不触发解码,也不影响video元素自身状态,只是提前建立连接和缓存
preload 生效的前提常被忽略:DOM 必须初始存在
这是最容易踩的坑——很多项目用 JS 动态渲染视频组件,却指望 preload 起作用。它只在 HTML 解析阶段参与资源调度,后续 JS 设置完全不触发浏览器预加载逻辑。
- 如果视频是懒加载组件的一部分,
preload属性写在模板里也没用,得靠 JS 显式调用load() - 微信 X5 内核对
<audio></audio>更激进:哪怕设none,只要调用play()就立即请求并缓存前 1–2MB,但<video></video>不享受此待遇 - 真要验证是否生效?打开浏览器网络面板,搜索
.mp4请求,看它是否在DOMContentLoaded完成前就发出了



















