track标签不支持preload属性,其加载完全依赖父媒体元素;预加载字幕需用并配CORS;track.readyState无LOADING态,仅0/2/3三值,无load事件。

track元素不支持preload属性,别白费劲写
直接说结论:track 标签根本没有 preload 属性,浏览器会忽略你写的 preload="metadata" 或任何值。W3C 规范里明确将其排除在可预加载资源类型之外——它不是“资源”,而是“轨道描述符”,依赖于 video 或 audio 元素的生命周期触发加载。
常见错误现象:在 <track kind="subtitles" src="zh.vtt" preload="auto"></track> 中加 preload,控制台无报错但字幕延迟出现,Lighthouse 也不把它当关键请求处理。
- 浏览器只在
video开始加载或播放时,才顺带发起track的src请求 -
track的加载时机完全受控于父媒体元素,无法独立触发 - 想“提前拉字幕”?只能靠
<link rel="preload" as="fetch" href="zh.vtt">手动干预
用预加载字幕文件要配对as值
手动预加载 track 的 src 是可行路径,但必须用对 as 值,否则浏览器不会复用缓存、甚至可能拒绝加载。
正确写法是:<link rel="preload" as="fetch" href="zh.vtt">。这里 as="fetch" 表示这是一个通过 fetch() 类似方式获取的文本资源,和 XMLHttpRequest 同级,符合 VTT 文件的实际加载机制。
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 错用
as="text"或as="script":浏览器可能忽略或降级为普通请求 - 必须放在
里,且在<video></video>标签之前,否则预加载时机晚于媒体元素自身请求 - 如果字幕文件带 CORS 头(比如托管在 CDN),
<link>预加载也需对应加crossorigin属性
字幕加载失败时,track.readyState永远卡在0
track 元素有个容易被忽略的状态机:track.readyState 只有 0(NOT_LOADED)、2(LOADED)、3(ERROR)三个值,**没有 1(LOADING)**。这意味着你监听不到“正在加载中”的中间态。
典型坑点:用 track.addEventListener('load', handler) 想等字幕就绪?没用——track 不触发 load 事件。只能靠轮询 readyState === 2,或监听父 video 的 loadedmetadata 后再检查。
- 网络超时、404、CORS 拒绝都会让
readyState停在 0,且无错误回调 - 想做 fallback(比如自动切换英文轨),得自己发
fetch()检查zh.vtt是否可读,不能依赖track自身状态 - 移动端 Safari 对 VTT 加载失败更静默,连控制台警告都可能不打
多语言字幕预加载要按需,别全塞进head
一个视频支持中/英/日三语字幕,不代表要把三个 <link rel="preload"> 全写进 。用户大概率只看一种语言,全预加载等于浪费带宽和 HTTP/2 流。
真实场景建议:只预加载默认语言(如页面 lang 属性匹配的),其余语言用 JS 按用户切换动作懒加载。
- 检测用户偏好:
navigator.language或服务端注入的data-default-track="zh" - 切换字幕时,用
fetch()加载目标 VTT,解析后调用track.addCue()动态注入(注意兼容性) - 避免在
video播放中频繁切换track.mode,Safari 有已知 bug:mode 切换后 cue 不渲染
最常被绕过的细节是:VTT 文件本身要压缩(Brotli > Gzip),且响应头必须含 Content-Type: text/vtt。少一个,Chrome 就不认作字幕资源,预加载缓存也不会命中。


















