Nano Hash - криптовалюты, майнинг, программирование

Google Chrome не поддерживает мультиплексирование с http2

Я создаю веб-приложение и обслуживаю его через http2. Однако, когда я анализирую сеть в инструментах разработчиков Google Chrome (версия 59.0.3071.115 (официальная сборка) (64-разрядная версия)), становится ясно, что мультиплексирование не работает, поскольку существует только 6 активных подключений (например, с http1.1). а остальные соединения ставятся в очередь.

Почему это? Или мои ожидания не соответствуют действительности?

Снимок экрана (видно, что протокол http2):

Вкладка сети Chrome показывает только 6 активных подключений, а остальные находятся в очереди, несмотря на использование http2

Обновление №1:

  • Бэкэнд работает на nginx 1.13;
  • Я использую загрузчик пользовательских модулей, который загружает сразу все сценарии (путем создания тега сценария с атрибутом async в цикле);
  • На снимке экрана показано, что для строки 8 и за ее пределами браузер получил запрос на начало загрузки ресурсов, но белая часть строки показывает, что эти сценарии были поставлены в очередь, а фактическая загрузка началась только тогда, когда слоты стали доступны (см. Как строки 8, 7 и 9 начните загрузку после завершения строк 2, 3 и 4; то же самое касается строк 11, 12, 13 и 5, 6, 7).

  • Сможете ли вы воспроизвести эту проблему на минимальном примере, которым вы могли бы поделиться? 30.07.2017
  • @FrederikDeweerdt благодарит за ответ; Я не могу показать текущую среду, но я настрою для этой цели другую, минималистичную, чтобы просто проверить, подтвердить проблему. 31.07.2017

Ответы:


1

Я думаю, что это ошибка 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:  Javascript без async или defer

С тегом async script скрипты загружаются параллельно группами по 6 - точно так, как вы отметили: Javascript с асинхронным режимом

Щелчок по ним показывает, что они БЫЛИ загружены через 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
  • Добавлен отзыв от команды Chrome. 25.08.2017
  • Привет из 2020, команда Chrome еще не исправила это :( 18.02.2020

  • 2

    Может быть несколько причин, по которым Chrome решает ограничить мультиплексирование при использовании HTTP / 2.

    Например, поведение сильно отличается, когда вы загружаете страницу с большим количеством изображений, в зависимости от того, отображаются ли изображения в области просмотра браузера или нет.

    Документы, которые вы загружаете, представляют собой сценарии, и сценарии могут блокироваться, зависеть друг от друга или иным образом изменять способ загрузки ресурсов браузером.

    Фактически, если вы перейдете к онлайн-примерам HTTP / 2, таким как https://http2.golang.org/gophertiles?latency=0, вы увидите, что Chrome действительно хорошо мультиплексирует загрузку изображений (но только если они отображаются в области просмотра).

    Поэтому в вашем случае это может быть что-то со скриптами; возможно, они зависят друг от друга, и поэтому Chrome не может мультиплексировать более шести одновременно.

    Я не удивлюсь, если это предел загрузчиков JavaScript, которые предполагают HTTP / 1.1 и теперь устарели с HTTP / 2.

    Вы можете использовать вкладку «Производительность» в Инструментах разработчика Chrome, чтобы узнать больше о производительности своей страницы.

    Вы также захотите изучить такие инструменты, как Page Speed ​​, которые дадут вам представление о том, как для оптимизации вашей страницы.

    Таким образом, я не думаю, что проблема заключается в том, как Chrome реализует HTTP / 2, а скорее в том, что в вашем приложении / скриптах есть что-то, что не оптимизировано для HTTP / 2.

    29.07.2017
  • Спасибо за ответ, но я не думаю, что какие-либо из ваших комментариев применимы в моем случае. См. Обновление №1 в исходном посте. Кроме того, Page Speed ​​не дал значимых результатов (я получил 100/100). 30.07.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..