Я думаю, что это ошибка Chrome или, по крайней мере, ненужное ограничение.
Это легко проверить.
Я создал простой пример HTML-файла, который загружает 25 копий одного и того же файла javascript (с параметром запроса, чтобы он выглядел как другой ресурс):
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Lots of JS files</title>
<meta name="robots" content="noindex">
<body>
</body>
<h1>This is a test for Lots of JS files</h1>
<script src="/assets/js/test.js?v=01"></script>
<script src="/assets/js/test.js?v=02"></script>
<script src="/assets/js/test.js?v=03"></script>
<script src="/assets/js/test.js?v=04"></script>
<script src="/assets/js/test.js?v=05"></script>
<script src="/assets/js/test.js?v=06"></script>
<script src="/assets/js/test.js?v=07"></script>
<script src="/assets/js/test.js?v=08"></script>
<script src="/assets/js/test.js?v=09"></script>
<script src="/assets/js/test.js?v=10"></script>
<script src="/assets/js/test.js?v=11"></script>
<script src="/assets/js/test.js?v=12"></script>
<script src="/assets/js/test.js?v=13"></script>
<script src="/assets/js/test.js?v=14"></script>
<script src="/assets/js/test.js?v=15"></script>
<script src="/assets/js/test.js?v=16"></script>
<script src="/assets/js/test.js?v=17"></script>
<script src="/assets/js/test.js?v=18"></script>
<script src="/assets/js/test.js?v=19"></script>
<script src="/assets/js/test.js?v=20"></script>
<script src="/assets/js/test.js?v=21"></script>
<script src="/assets/js/test.js?v=22"></script>
<script src="/assets/js/test.js?v=23"></script>
<script src="/assets/js/test.js?v=24"></script>
<script src="/assets/js/test.js?v=25"></script>
</html>
Затем я сделал то же самое, но добавил атрибут async на случай, если Chrome решит заблокировать загрузку во время обработки Javascript:
<script src="/assets/js/test.js?v=01" async=""></script>
<script src="/assets/js/test.js?v=02" async=""></script>
....etc.
и то же самое, но с атрибутом defer:
<script src="/assets/js/test.js?v=01" defer=""></script>
<script src="/assets/js/test.js?v=02" defer=""></script>
....etc.
Файл /assets/js/test.js
был пуст. Таким образом, не будет ни задержек выполнения, ни зависимостей, кроме тех, которые добавлены браузером.
Я увидел интересные результаты! Это все с Chrome 60.0.3112.78 или 60.0.3112.101, и я использую Apache, но увидел те же результаты, что и для Nginx.
С сервером HTTP / 2 мы видим следующие результаты:
С помощью простого тега script
все сценарии загружаются параллельно (но предположительно выполняются по порядку). Нет ограничения в 6 подключений, как в HTTP / 1.1:
С тегом async script
скрипты загружаются параллельно группами по 6 - точно так, как вы отметили:
Щелчок по ним показывает, что они БЫЛИ загружены через HTTP / 2.
С тегом defer script
сценарии аналогичны результатам использования тега async - ограничение до 6 загрузок за раз.
Это не имеет смысла - Chrome ограничивает ваши загрузки Javascript, но только в том случае, если вы используете async или defer, чтобы улучшить свои загрузки, не блокируя рендеринг!
Как заявил sbordet, то же самое не происходит с изображениями в области просмотра - поэтому мультиплексирование ДЕЙСТВИТЕЛЬНО работает в Chrome, просто кажется, что оно без необходимости ограничено для Javascript в асинхронном или отложенном режиме. Это реальное ограничение, если вы планируете больше не связывать скрипты вместе под HTTP / 2, поскольку многие советуют вам больше не делать этого.
Этого не происходит ни в Firefox, ни в Edge. Хотя это действительно происходит в Opera (браузере на основе Chromium).
Так что это плохие новости. Хорошая новость в том, что они "возможно" исправили это. Когда я пробую Chrome Canary (62.0.3190.0), я не могу повторить это поведение. Однако, когда я использую тест веб-страницы с Canary (который дает 62.0.3190.1 в строке пользовательского агента, поэтому должен быть практически таким же), он является повторяемым, поэтому не на 100% уверен, что они исправили это после все...
Сообщили об ошибке в команде Chrome, чтобы узнать, что они скажут: https://bugs.chromium.org/p/chromium/issues/detail?id=757191
В целом, HTTP / 2 как на сервере, так и на клиенте в настоящий момент кажется немного изменчивым, поскольку обе стороны настраивают и настраивают свои реализации, чтобы оптимально использовать этот все еще относительно новый протокол. Тем не менее, удивительно видеть, что Chrome ударил этим, поскольку Google начал это со своей реализацией SDPY (на которой в значительной степени основан HTTP / 2), поэтому вы ожидаете, что они будут впереди кривой, а не позади ...
** Обновлять **
Команда Chrome вернулась и подтвердила, что это ограничение текущей реализации HTTP / 2 в Chrome. Они наблюдали проблемы с производительностью, когда многие ресурсы вызывались одновременно, как позволяет HTTP / 2, поэтому ограничьте некритические элементы (включая async / defer и элементы, не видимые в области просмотра) ограничением HTTP / 1.1 равным 6.
Несмотря на то, что HTTP / 2 имеет концепцию приоритезации запросов после их отправки, проблемы с производительностью были замечены до того, как они были приоритизированы и отправлены (например, проверка кеша, файлов cookie и т. Д.), Поэтому приоритизация HTTP / 2 здесь не помогает.
Они надеются улучшить это в будущем.
Думаю, я был прав, что это проблема реализации, поскольку мы привыкаем к новому миру HTTP / 2 и должны оптимизировать для него наши браузеры и серверы!
19.08.2017