移动chrome中preload="none"不保证禁用元数据加载,小体积mp4(≤2mb)在特定条件下会静默预读前几kb触发loadedmetadata;验证需观察网络请求与事件时机,彻底禁用须延迟创建video并手动load。

preload="none"在移动Chrome是否仍预加载元数据?
不会主动加载元数据,但存在「静默预读」例外:当视频文件体积很小(实测 ≤ 2MB 的 MP4),且页面已加载完成、video 元素已挂载 DOM,移动 Chrome 可能悄悄发起请求并缓存头几个字节——这足以解析出时长、宽高,表现为 loadedmetadata 意外触发。这不是规范行为,而是实现层面的优化副作用。
如何验证 mobile Chrome 是否真跳过了 preload
别信属性值,看网络请求和事件时机才是铁证:
- 打开 Chrome DevTools → Network 面板 → 过滤
.mp4或.m4a,刷新页面;若在用户点击前就出现请求,说明预加载发生了(哪怕写了preload="none") - 监听
loadstart和loadedmetadata;如果这两个事件在用户手势(click/touchend)前就触发,那元数据已被加载 - 检查
video.networkState:页面刚加载完时若为0(NETWORK_EMPTY),基本可确认未加载;若为1(NETWORK_IDLE)且video.buffered.length > 0,说明已有数据进缓冲区
为什么写了 none 还会“漏”出元数据
根本原因在于:preload 是提示,不是指令。移动 Chrome 在以下条件下可能降级处理但不完全遵守:
- 视频 URL 是同源、无鉴权参数、响应头支持
Accept-Ranges: bytes - 元素已渲染(非
display: none或未 append 到 DOM) - 页面处于前台、网络状态良好(如 Wi-Fi)、设备内存充足
- video 标签有
controls属性,浏览器推测用户大概率会播
此时它可能只 fetch 前 64KB(足够解析 MP4 moov box),然后停住——这就导致 loadedmetadata 触发,但 canplay 不触发,video.buffered.end(0) 返回 0。
想彻底禁用元数据加载,该怎么做
靠 HTML 属性做不到,必须结合 JS 控制生命周期:
- 不要在页面初始化时就创建
video元素;延迟到用户交互后动态document.createElement('video') - 创建后先设
preload = "none",再appendChild,再调video.load()(注意:此时才真正启动加载) - 若需提前知道时长,放弃依赖
preload,改用 Blob +FileReader解析本地文件头,或服务端返回 JSON 元信息接口 - 对关键路径(如首屏视频),直接用
preload="metadata"+loadedmetadata监听,比赌none更可控
最常被忽略的一点:移动端媒体加载永远以用户手势为起点,preload 的任何“预期行为”都只是桌面环境下的经验,在 iOS 和 Android WebView 中几乎不可靠——写 none 是为了表意和降级兜底,不是为了精确控制。











