preload 是浏览器加载提示而非开关,需配合 load() 和 canplaythrough 等媒体 API 使用;其合法值为 none、metadata、auto,分别对应跳过预加载、仅加载元数据、由浏览器决定,但实际效果受 DOM 状态、src 设置时机、设备策略、响应头及 autoplay 等因素影响。

preload 属性本身不是加载开关,而是浏览器的加载提示。真正提升媒体加载性能,关键在于把它和媒体 API(比如 load()、canplaythrough 事件)配合使用,尤其在需要快速响应用户操作的场景下。
明确 preload 的三种取值与实际效果
preload 只接受 none、metadata、auto 三个合法值,其他写法(如 "true" 或空字符串)会被当作 none 处理:
- preload="none":建议跳过所有预加载。多数浏览器仍可能拉取首帧或少量数据用于尺寸判断,但不会加载元信息或音视频帧
- preload="metadata":仅请求容器头部(如 MP4 的 moov box),用于获取时长、宽高、编码格式等。这是最常用也最稳妥的选择,兼容性好、省流量、支持进度条显示
- preload="auto":浏览器可完全忽略。Chrome 桌面版常按 metadata 处理;iOS Safari 则一律降级为 none,无论你怎么写
为什么写了 preload 却没加载?常见原因
这不是代码错误,而是浏览器主动抑制了加载行为。以下情况会直接导致 preload 不生效:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 元素尚未插入 DOM(比如还在 DocumentFragment 中,或 display: none 但父节点未挂载)
- src 是 JS 后续动态设置的——preload 只在初始 HTML 解析阶段起作用
- 设备开启低电量模式或“节省流量”设置,Chrome/Firefox/Safari 会自动降级为 metadata 或跳过
- 服务端响应头缺失
Accept-Ranges: bytes,导致 metadata 模式无法分段请求,部分浏览器干脆放弃加载 - 设置了
autoplay,桌面浏览器可能绕过 preload 直接加载;但 iOS Safari 禁止自动播放,此时 preload="auto" 也无效
用 load() + 事件监听替代纯依赖 preload
当业务强依赖媒体快速就绪(比如点击即播、游戏音效、通知提示音),不能只靠 preload 提示,必须主动控制:
立即学习“前端免费学习笔记(深入)”;
- 确保
<video></video>或<audio></audio>已挂载到 DOM(visibility: hidden 或 position: absolute 都可以,只要在 document.body 下) - 先设
preload="none",再赋值src,然后立即调用.load()方法触发完整加载流程 - 监听
canplaythrough事件而非loadeddata,它表示浏览器判断当前缓冲足以播放到结束,更适合判断“是否 ready” - 若已进入
loadedmetadata状态,再次调用load()不会重发请求,需先清空 src 再重设
配合 link[preload] 提前发起网络请求
对于首屏关键媒体(如英雄视频、引导音频),<link rel="preload"> 比 video/audio 上的 preload 更早介入资源获取:
-
<link rel="preload" href="hero.mp4" as="video" crossorigin>—— 告诉浏览器在解析 HTML 阶段就发起请求 - 必须指定准确的
as值(video/audio/font/style/script),否则可能被忽略或降级为普通 GET - 跨域资源需加
crossorigin属性,否则可能因 CORS 策略失败 - 它不触发解码,只是提前下载;后续仍需通过 video/audio 元素或 JS 创建实例来播放


















