能,但仅当视频元素从未调用load()或play()时成立;此时浏览器跳过DNS/TCP/TLS,readyState保持0,服务器收不到任何请求。

preload="none" 真的能省服务器带宽吗
能,但只在视频元素从未被调用 load() 或 play() 的前提下成立。它让浏览器跳过 DNS、TCP、TLS 全流程,video.readyState 长期为 0(HAVE_NOTHING),连 poster 封面帧都拿不到——服务器根本收不到任何字节范围请求或完整 GET 请求。
常见错误现象:
- 写了
preload="none"却在页面初始化就监听loadedmetadata,事件永远不触发 - 列表页所有
<video></video>都设为none,但没配IntersectionObserver,用户滑到眼前才调load(),首帧延迟 >2s - 误以为 Chrome 对本地 MP4 会彻底静默——它可能仍发一个
Range: bytes=0-1023请求,只为读宽高,服务器照样要响应
preload="metadata" 为什么常比 none 更耗服务器流量
它本意只取 moov box(几 KB),但生效有硬依赖:服务端必须返回 Accept-Ranges: bytes,且视频文件经 ffmpeg -c copy -movflags +faststart 重写。否则浏览器无法做字节范围请求,只能一路下载直到 moov 出现——对 500MB 视频,可能拉下前 20MB 才解析出时长。
容易被忽略的服务器配置问题:
立即学习“前端免费学习笔记(深入)”;
- Nginx 默认不给 MP4/MP3 加
Accept-Ranges响应头,需手动加add_header Accept-Ranges bytes; - CDN 缓存了不含
Accept-Ranges的旧响应,后续所有请求继承该缺陷 - FFmpeg 转码时漏掉
+faststart,moov 在文件末尾,服务器得把整个文件读完才能返回元数据
preload="auto" 对服务器带宽基本无效
名字带 “auto”,实际从不自动全量加载。iOS Safari 无视该值,静默降级为 none;Chrome 桌面版通常只请求前 1–5 秒数据;Android WebView 和微信 X5 内核普遍退化为 metadata。更关键的是:只要写了 autoplay,preload 直接被忽略——不是 bug,是规范行为。
真正影响服务器压力的,是浏览器是否发起请求、请求多少字节。而 auto 给出的只是模糊建议,服务器无法据此做连接复用或流控决策。
- 不要给信息流中几十个视频都设
auto,大文件(>100MB)下极易触发并发连接风暴 - 动态 JS 设置
video.preload = "auto"完全不触发预加载逻辑,只在 HTML 解析阶段起作用 - 微信 X5 内核对首次
load()有静默丢弃风险,建议加setTimeout(() => video.load(), 0)微调
真正节省服务器带宽的实操组合
单靠 preload 属性无法确定性节流。必须把控制权从 HTML 移交给 JS,并确保每次请求都有明确意图和上下文。
- 用
IntersectionObserver监听视口,仅当视频即将可见时才调video.load(),避免提前建立 TCP 连接 - 通过
navigator.connection.effectiveType检测网络类型(如'2g'、'slow-2g'),弱网下强制设preload="none"并禁用link rel="preload" - 关键视频用
<link rel="preload" as="video" href="xxx.mp4">,但注意:仅同域有效,且必须带as="video",否则不触发 high-priority 请求 - 服务端开启 HTTP/2 多路复用 + Brotli 压缩,对 moov box 类小响应效果显著;对大视频启用分片(DASH/HLS)而非单 MP4
最易被忽略的一点:哪怕所有配置都对,只要 <video></video> 是 JS 动态插入 DOM 的,preload 属性就完全失效——它只参与 HTML 解析阶段的资源调度,不响应后续 DOM 变更。



















