Непоследовательное поведение порядка загрузки для ресурсов, загруженных (Chrome) - PullRequest
2 голосов
/ 25 апреля 2020

Я экспериментирую с динамическим добавлением тега <link rel="preload"> для загрузки файлов шрифтов на основе пользовательского соединения navigator.connection.effectiveType, например, если эффективный тип равен 4g, введите <link as="font" type="font/woff2" rel="preload" crossorigin="anonymous" href="inter-var.woff2"> в тег head перед любыми другими ресурсами, если соединение «медленное-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>

Проблема, с которой я сталкиваюсь является то, что Chrome не сохраняет первоначальный порядок для ресурсов, загруженных с предварительной загрузкой ссылки, если элемент link был создан с JavaScript (если элементы ссылки встроены как HTML в теге head, все работает как ожидалось ).

Снимок экрана:

  • Safari (соответствует исходному порядку)
  • Chrome (не соответствует исходному порядку)
  • Firefox (не поддерживает предварительную загрузку ссылки)

Safari, Chrome, Firefox

Я пытаюсь понять, почему исходный ордер ломается в Chrome и можно ли его исправить?

1 Ответ

1 голос
/ 25 апреля 2020

Chrome инженер здесь. Здесь есть несколько несоответствий, из того, что я могу сказать:

  1. Во-первых, вы можете видеть, что Firefox на самом деле извлекает image.jpeg и до предварительной загрузки, учитывая ваше изображение
  2. Во-вторых, я иногда могу заставить Safari также создать странный порядок:

Safari ordering

Здесь вы видите Chrome * (и некоторых других браузеров) фоновый парсер HTML в работе, который является еще одним легковесным парсером, который быстро просматривает страницу в поисках ресурсов для умозрительного (раннего) извлечения. После небольшой отладки Chrome на странице примера, которую вы создали, порядок происходящих событий примерно такой:

  1. Спекулятивный анализатор запускает запрос на script.js
  2. Спекулятивный Парсер запускает запрос для image.jpeg
  3. Обычный парсер выполняет ожидающий сценарий блокировки синтаксического анализа документ
  4. Три предварительные загрузки извлекаются в порядке их добавления

Таким образом, в этом случае вы видите, что анализатор спекулятивных / фоновых событий немного забегает вперед, и начинаете извлекать информацию, прежде чем основной анализатор сможет сделать это через ваш тег script. У большинства браузеров такой синтаксический анализатор есть статья об этом , и, к сожалению, он не указан ни в одном стандарте, поскольку он не должен иметь никаких наблюдаемых (для кода приложения) эффектов.

Однако, если вы видите проблему с производительностью из-за этого, лучше всего подать сообщение об ошибке Chromium на https://crbug.com и, возможно, дайте мне знать, и я смогу сообщить об этом нужным людям. .

PS Я заметил, вы подали https://github.com/w3c/preload/issues/146, которую я, вероятно, закрою в пользу того, чтобы вы подали ошибку Chrome, если все в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...