preload不是开关而是可忽略的提示;iOS Safari中preload="auto"无效,真正可靠的是preload="metadata"(需服务端支持Accept-Ranges和faststart)及JS显式调用load()。

preload 不是开关,是浏览器可忽略的提示;写 preload="auto" 在 iOS Safari 里等于没写,真正能靠得住的只有 preload="metadata"(且需服务端配合)和 JS 显式调用 load()。
preload="metadata" 为什么最稳妥,但常失效
它本意只拉视频头信息(moov box),体积小、速度快,但失效后反而更糟——浏览器可能下载前几 KB 甚至整个文件来“猜”时长。两个硬条件缺一不可:
- 服务端响应头必须含
Accept-Ranges: bytes,否则无法发字节范围请求 - MP4 文件必须经
ffmpeg -c copy -movflags +faststart重写,确保 moov 在开头 - 未满足任一条件时,
loadedmetadata事件会严重延迟,video.duration长期为NaN
preload="none" 不是“零请求”,而是把加载时机交给你
设为 none 后,src 赋值不会触发任何网络请求,连 DNS 查询都跳过。但它不是绝对静默:
- Chrome 等浏览器仍可能对小 MP4 发
Range: bytes=0-1023请求,只为读宽高和编码格式 - 用户点击播放时,浏览器会 fallback 自动调用
load(),但此时进度条空白、无缓冲指示,体验割裂 - 想实现滚动预加载?必须搭配
IntersectionObserver监听进入视口,再手动设src并调用load()
preload="auto" 在哪些场景真有用
它在桌面 Chrome 对首屏核心视频(≤2MB、H.264 编码)有一定效果,但有严格前提:
立即学习“前端免费学习笔记(深入)”;
- 页面已获得用户焦点(非后台 tab)
- 未开启省电模式或 Low Data Mode
-
autoplay和preload="auto"同时存在时,后者直接被忽略 - 移动端(iOS/安卓 WebView)基本无视该值,Safari 从 iOS 10 起强制降级为
none
link rel="preload" as="video" 是个陷阱
它和 <video preload></video> 完全不互通,且行为极不稳定:
- 跨域视频必须加
crossorigin,否则请求发出去也进不了缓存(状态码显示 0) - Safari 完全忽略
as="video",Chrome 优先级常被降为 Low,不如as="fetch"可靠 - 即使成功预加载,
<video></video>元素仍会发自己的请求,造成重复下载 - 真正可控的做法:同域下用
<link rel="preload" as="fetch" crossorigin>抢带宽,再由 JS 控制video.load()
最易被忽略的点:preload 只在 HTML 初始解析阶段生效;动态插入的 <video></video> 元素,无论怎么设 preload,都不会触发预加载——你得亲手调 load(),而不是指望属性自动工作。



















