javascript - 使用 <link rel ="preload"> (Chrome) 加载的资源的加载顺序行为不一致

标签 javascript html http cross-browser

我正在尝试动态添加 <link rel="preload">基于用户连接加载字体文件的标签navigator.connection.effectiveType ,例如如果有效类型是“4g”注入(inject)<link as="font" type="font/woff2" rel="preload" crossorigin="anonymous" href="inter-var.woff2">head在任何其他资源之前标记,如果连接是 'slow-2g'/'2g'/'3g' 不要注入(inject) link .

我还使用 preload 加载其他资源, 但它们不像字体那么重要,因此它们在字体文件之后注入(inject)。

<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,Chrome 不会保留使用链接预加载加载的资源的原始顺序。元素是用 JavaScript 创建的(如果链接元素在 head 标记中作为 HTML 内联,一切都按预期工作)。

截图:

  • Safari(尊重原始顺序)
  • Chrome(不遵守原始顺序)
  • Firefox(不支持链接预加载)

Safari, Chrome, Firefox

我想了解为什么原始订单在 Chrome 中中断,是否可以修复?

最佳答案

这里是 Chrome 工程师。据我所知,这里有一些不一致之处:

  1. 首先,您可以看到 Firefox 实际上也在预加载之前获取 image.jpeg,给定您的图片
  2. 其次,实际上我偶尔也会让 Safari 产生奇怪的顺序:

Safari ordering

您在这里看到的是 Chrome(和其他一些浏览器)的后台 HTML 解析器在工作,它只是另一个轻量级解析器,可以快速浏览页面以寻找资源以推测(早期)获取。通过在您创建的示例页面上对 Chrome 进行一些调试,事件发生的顺序大致如下:

  1. 推测解析器启动对 script.js
  2. 的请求
  3. 推测解析器开始请求 image.jpeg
  4. 普通解析器执行文档的挂起解析阻止脚本
  5. 按照添加的顺序获取三个预加载

所以在这种情况下,您会看到推测/后台解析器向前跳了一点,并在主解析器能够通过您的 script 标记之前开始获取内容。大多数浏览器都有这种解析器 here's an article about it ,不幸的是它没有被任何标准指定,因为它不应该有任何可观察到的(对应用程序代码)影响。

但是,如果您因此而遇到性能问题,最好的办法是在 https://crbug.com 上提交 Chromium 错误。也许让我知道,我可以在合适的人面前展示它。

附言我注意到你提交了 https://github.com/w3c/preload/issues/146 ,如果可以的话,我可能会关闭以支持您提交 Chrome 错误。

关于javascript - 使用 <link rel ="preload"> (Chrome) 加载的资源的加载顺序行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61419382/

相关文章:

javascript - 始终将 jQuery 弹出窗口放在页面中央?

javascript - 如何使用jsoup选择当前div内的img标签

Javascript-有没有办法通过对象名称作为字符串来测试对象的instanceof

javascript - 添加幻灯片后初始化 slider

javascript - 用于突出显示和提醒网页上所有链接的 Google Chrome 扩展程序

HTML 按钮样式不正确

python - 在 Django 中测试 cookie 是否存在

php - 从具有 localhost 的主机访问 Vagrant 机器上的 symfony web 服务器

javascript - 当我想发布 JSON 文件 HTTP REQUEST 时,为什么会收到错误 400

javascript - 如何将类切换到 v-for 中的单个元素