使用 <link rel="preload"> (Chrome) 加载的资源的加载顺序行为不一致
Inconsistent load order behavior for the resources loaded with <link rel="preload"> (Chrome)
我正在尝试动态添加 <link rel="preload">
标签以根据用户连接 navigator.connection.effectiveType
加载字体文件,例如如果有效类型是“4g”,则在任何其他资源之前在 head
标记中注入 <link as="font" type="font/woff2" rel="preload" crossorigin="anonymous" href="inter-var.woff2">
,如果连接是 'slow-2g' / “2g” / “3g”,则不要注入 link
.
我也在使用 preload
加载其他资源,但它们不像字体那么重要,因此它们是在字体文件之后注入的。
<head>
// some other code
<script id="connection-type-checker">
(() => {
const inter = document.createElement('link')
const interItalic = document.createElement('link')
const firaCode = document.createElement('link')
inter.as = 'font'
inter.type = 'font/woff2'
inter.rel = 'preload'
inter.crossOrigin = 'anonymous'
inter.href = 'inter-var.woff2'
interItalic.as = 'font'
interItalic.type = 'font/woff2'
interItalic.rel = 'preload'
interItalic.crossOrigin = 'anonymous'
interItalic.href = 'inter-var-italic.woff2'
firaCode.as = 'font'
firaCode.type = 'font/woff2'
firaCode.rel = 'preload'
firaCode.crossOrigin = 'anonymous'
firaCode.href = 'fira-code.woff2'
const insertAfter = (newNode, referenceNode) => referenceNode
.parentNode.insertBefore(newNode, referenceNode.nextSibling)
const target = document.getElementById('connection-type-checker')
insertAfter(inter, target)
insertAfter(interItalic, target)
insertAfter(firaCode, target)
})()
</script>
// **This is where <link>s get injected**
// some other code...
<link as="script" rel="preload" href="script.js" crossorigin="anonymous">
</head>
我面临的问题是,如果 link
元素是使用 [=55= 创建的,那么 Chrome 不会保持使用 link 预加载加载的资源的原始顺序](如果 link 元素在 head
标记中内联为 HTML,则一切正常。
截图:
- Safari(尊重原始顺序)
- Chrome(不尊重原来的顺序)
- Firefox(不支持 link 预加载)
我想了解为什么原始订单在 Chrome 中中断,是否可以修复?
Chrome 工程师在这里。据我所知,这里有一些不一致之处:
- 首先,根据您的图片,您可以看到 Firefox 实际上也在预加载之前获取
image.jpeg
- 其次,实际上我偶尔也会让 Safari 产生奇怪的顺序:
您在这里看到的是 Chrome(和其他一些浏览器)的后台 HTML 解析器在工作,它只是另一个轻量级解析器,可以快速浏览页面以寻找推测性(早期)获取的资源。通过在您创建的示例页面上调试 Chrome,事件发生的顺序大致为:
- 推测解析器启动了对
script.js
的请求
- 推测解析器启动了对
image.jpeg
的请求
- 普通解析器执行文档的挂起解析阻止脚本
- 按照添加的顺序获取三个预加载
所以在这种情况下,您会看到 speculative/background 解析器向前跳了一点,并在主解析器能够通过您的 script
标记之前开始获取内容。大多数浏览器都有这种解析器 here's an article about it,不幸的是它没有被任何标准指定,因为它不应该有任何可观察到的(对应用程序代码)影响。
但是,如果您因此而遇到性能问题,最好的办法是在 https://crbug.com 上提交 Chromium 错误,也许让我知道,我可以在合适的人面前找到它.
P.S。我注意到你提交了 https://github.com/w3c/preload/issues/146,如果可以的话,我可能会支持你提交一个 Chrome 错误。
我正在尝试动态添加 <link rel="preload">
标签以根据用户连接 navigator.connection.effectiveType
加载字体文件,例如如果有效类型是“4g”,则在任何其他资源之前在 head
标记中注入 <link as="font" type="font/woff2" rel="preload" crossorigin="anonymous" href="inter-var.woff2">
,如果连接是 'slow-2g' / “2g” / “3g”,则不要注入 link
.
我也在使用 preload
加载其他资源,但它们不像字体那么重要,因此它们是在字体文件之后注入的。
<head>
// some other code
<script id="connection-type-checker">
(() => {
const inter = document.createElement('link')
const interItalic = document.createElement('link')
const firaCode = document.createElement('link')
inter.as = 'font'
inter.type = 'font/woff2'
inter.rel = 'preload'
inter.crossOrigin = 'anonymous'
inter.href = 'inter-var.woff2'
interItalic.as = 'font'
interItalic.type = 'font/woff2'
interItalic.rel = 'preload'
interItalic.crossOrigin = 'anonymous'
interItalic.href = 'inter-var-italic.woff2'
firaCode.as = 'font'
firaCode.type = 'font/woff2'
firaCode.rel = 'preload'
firaCode.crossOrigin = 'anonymous'
firaCode.href = 'fira-code.woff2'
const insertAfter = (newNode, referenceNode) => referenceNode
.parentNode.insertBefore(newNode, referenceNode.nextSibling)
const target = document.getElementById('connection-type-checker')
insertAfter(inter, target)
insertAfter(interItalic, target)
insertAfter(firaCode, target)
})()
</script>
// **This is where <link>s get injected**
// some other code...
<link as="script" rel="preload" href="script.js" crossorigin="anonymous">
</head>
我面临的问题是,如果 link
元素是使用 [=55= 创建的,那么 Chrome 不会保持使用 link 预加载加载的资源的原始顺序](如果 link 元素在 head
标记中内联为 HTML,则一切正常。
截图:
- Safari(尊重原始顺序)
- Chrome(不尊重原来的顺序)
- Firefox(不支持 link 预加载)
我想了解为什么原始订单在 Chrome 中中断,是否可以修复?
Chrome 工程师在这里。据我所知,这里有一些不一致之处:
- 首先,根据您的图片,您可以看到 Firefox 实际上也在预加载之前获取
image.jpeg
- 其次,实际上我偶尔也会让 Safari 产生奇怪的顺序:
您在这里看到的是 Chrome(和其他一些浏览器)的后台 HTML 解析器在工作,它只是另一个轻量级解析器,可以快速浏览页面以寻找推测性(早期)获取的资源。通过在您创建的示例页面上调试 Chrome,事件发生的顺序大致为:
- 推测解析器启动了对
script.js
的请求
- 推测解析器启动了对
image.jpeg
的请求
- 普通解析器执行文档的挂起解析阻止脚本
- 按照添加的顺序获取三个预加载
所以在这种情况下,您会看到 speculative/background 解析器向前跳了一点,并在主解析器能够通过您的 script
标记之前开始获取内容。大多数浏览器都有这种解析器 here's an article about it,不幸的是它没有被任何标准指定,因为它不应该有任何可观察到的(对应用程序代码)影响。
但是,如果您因此而遇到性能问题,最好的办法是在 https://crbug.com 上提交 Chromium 错误,也许让我知道,我可以在合适的人面前找到它.
P.S。我注意到你提交了 https://github.com/w3c/preload/issues/146,如果可以的话,我可能会支持你提交一个 Chrome 错误。