Изначально я поместил весь свой javascript в голову, но потом заметил, что время загрузки страницы было очень медленным - неудивительно. Итак, я переместил все свои скрипты вниз, чтобы устранить эффекты блокировки рендеринга DOM.
На странице Google PageInsights говорят, что это уже не лучшая практика, и рекомендуют поместить скрипты в голову и добавить асинхронную загрузку.
https://developers.google.com/speed/docs/insights/BlockingJS
Проблема, с которой я столкнулся, и насколько я понимаю, заключается в том, что если вы используете async, скрипт будет выполняться, как только он завершит загрузку, поэтому вы можете столкнуться с проблемами зависимости - именно это произошло с jQuery и сценариями, которые от него зависели. .
https://calendar.perfplanet.com/2016/prefer-defer-over-async/
Я обнаружил, что есть атрибут defer, который похож на async, но откладывает выполнение до загрузки. Если это так, почему я все еще сталкиваюсь с этими ошибками зависимости?
Это случается не каждый раз. Так получилось, что иногда скрипты, зависящие от jQuery, загружаются быстрее, чем сам jQuery, как показано ниже.
У меня вопрос: что мне делать, чтобы все загружалось асинхронно, но не выполнялось до завершения загрузки?
Надеюсь, это простое исправление без тонны причудливого javascript.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Note that asynchronous scripts are not guaranteed to execute in specified order and should not use document.write. Scripts that depend on execution order or need to access or modify the DOM or CSSOM of the page may need to be rewritten to account for these constraints.
Простое предложение: просто разместите свои скрипты внизу или используйте только тег async, если у них нет никаких зависимостей.
Все, что зависит от JQuery, зависит от того, сначала выполняется (загружается) JQuery.
Также лучшей практикой может быть фрагмент файла пакета, микроорганизация последовательности загрузки и использование CDN с блокировщиком кеша по мере необходимости (если вы не используете управление версиями), но на данном этапе это звучит как чрезмерная оптимизация.
В качестве альтернативы, если я правильно смотрю на ваш код, вам нужно отложить строку сценария ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js.
Вы все еще загружаете свой jquery-скрипт с помощью async, измените его также на defer.
Некоторые дополнительные сведения об async и defer, которые вы, возможно, уже знаете:
async: загружает ваш скрипт во время рендеринга браузера, затем останавливает рендеринг после завершения загрузки этого скрипта и выполняет его, а затем продолжает рендеринг.
defer: загружает ваш скрипт, пока браузер выполняет рендеринг, затем подождите, пока DOM закончит рендеринг, прежде чем выполнять ваши скрипты в правильном порядке (ТОЛЬКО если они также имеют атрибут src).
От MDN:
"отложить Этот логический атрибут установлен, чтобы указать браузеру, что сценарий предназначен для выполнения после анализа документа, но перед запуском DOMContentLoaded. Этот атрибут нельзя использовать, если атрибут src отсутствует (например, для встроенных скриптов), в этом случае он не будет иметь никакого эффекта.
Чтобы добиться аналогичного эффекта для динамически вставляемых скриптов, используйте вместо этого async = false. Сценарии с атрибутом defer будут выполняться в том порядке, в котором они указаны в документе ".
Отложить загрузки в асинхронном режиме, но выполняется по порядку, если только атрибут src не отсутствует в теге скрипта. [MDN] [1] [1]: developer.mozilla.org/en-US/docs/Web/HTML/Element/script