文件不能用rel="preload",因规范未定义as="track";应将直接写在/标签内靠前位置,确保静态src和crossorigin属性,并通过DevTools验证其由parser发起且早于DOMContentLoaded加载。

track 文件不能用 rel="preload"
浏览器不支持对 <track></track> 元素引用的字幕/描述文件(如 VTT)使用 rel="preload"。即使你写成 <link rel="preload" href="sub.vtt" as="fetch">,它也不会被识别为 track 资源,更不会自动挂载到 <video></video> 或 <audio></audio> 上。原因很简单:preload 的 as 值里没有 "track" 这个类型,W3C 规范也未定义该语义。
正确做法是让 track 加载时机尽可能早
<track></track> 本身已是声明式加载机制,但它的触发依赖于父媒体元素的解析和加载流程。要让它“提前加载”,关键不是预加载,而是确保它尽早出现在 DOM 中、且不被 JS 动态插入延迟:
- 把
<track></track>标签直接写在<video></video>或<audio></audio>开始标签之后、第一个<source></source>之前(规范推荐位置) - 避免在
DOMContentLoaded或useEffect里用 JS 创建并 append<track></track>—— 这会等到 JS 执行才开始请求,通常晚于首帧渲染 - 确保
src是静态路径,不要拼接变量或表达式,例如src="/subs/en.vtt"可行,src="/subs/${lang}.vtt"是纯文本,会 404 - 若字幕文件托管在跨域 CDN,必须加
crossorigin属性(哪怕同协议同域名),否则 Chrome/Safari 会拒绝加载
想强制提前拉取 VTT?用 as="fetch" + 手动缓存
如果你确实需要在 <video></video> 解析前就发起 VTT 请求(比如做自定义字幕加载器),唯一可行路径是绕过 <track></track>,改用 fetch() 预取并存入 cache:
fetch('/subs/en.vtt')
.then(r => r.text())
.then(text => {
// 存入 sessionStorage 或用 URL.createObjectURL(new Blob([text]))
// 后续通过 JS 注入 TextTrack 或动态创建 track 元素
});
注意:as="fetch" 的 <link rel="preload"> 虽能触发请求,但它不会设置正确的 Accept 头(VTT 需要 text/vtt),也不保证进 HTTP 缓存池供后续 <track></track> 复用,所以不如直接 fetch 控制力强。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
立即学习“前端免费学习笔记(深入)”;
验证 track 是否真正早加载
别只看 HTML 里有没有写 <track></track>,打开 Chrome DevTools → Network → 刷新页面,筛选 .vtt,观察三点:
- Initiator 列是否为
parser(说明是 HTML 解析阶段触发)而不是script或空 - Start Time 是否落在
DOMContentLoaded之前 200ms 内 - Status 是否为
200(非304或pending),且没有因 missingcrossorigin导致的 CORS 错误
最常被忽略的是:即使 <track></track> 写在 HTML 里,如果父 <video></video> 的 src 是空或动态设置的,浏览器根本不会启动 track 加载 —— 它必须看到一个可解析的媒体源才会处理子 <track></track>。


















