Якщо ви не завантажуєте динамічно сценарії або не позначаєте їх як defer
або async
, то сценарії завантажуються у порядку, який зустрічається на сторінці. Не має значення, чи це зовнішній сценарій чи вбудований сценарій - вони виконуються в тому порядку, з яким вони стикаються на сторінці. Вбудовані сценарії, що надходять після зовнішніх скриптів, зберігаються до тих пір, поки всі зовнішні скрипти, що надійшли до них, не завантажуються та не запускаються.
Сценарії асинхронізації (незалежно від того, як вони вказані як асинхронізація) завантажуються та виконуються у непередбачуваному порядку. Браузер завантажує їх паралельно, і він може запускати їх у будь-якому порядку.
Немає передбачуваного порядку серед кількох речей асинхронізації. Якщо потрібен передбачуваний порядок, його потрібно буде закодувати, зареєструвавши повідомлення про завантаження із сценаріїв асинхронізації та послідовно виконуючи вручну виклики javascript, коли завантажуються відповідні речі.
Коли тег скрипту буде вставлено динамічно, то, як поводиться порядок виконання, залежатиме від браузера. У цій довідковій статті ви можете подивитися, як веде себе Firefox . Коротше кажучи, новіші версії Firefox за замовчуванням динамічно додаються теги сценарію для асинхронізації, якщо тег сценарію не встановлено інакше.
Тег сценарію з async
може запускатися, як тільки він завантажується. Насправді, браузер може призупинити аналізатор від того, що він робив, і запустити цей сценарій. Отже, це дійсно може працювати майже в будь-який час. Якщо сценарій був кешований, він може працювати майже відразу. Якщо сценарій завантажується деякий час, він може запуститися після того, як буде виконано аналізатор. Єдине, що слід пам’ятати, async
це те, що він може працювати в будь-який час і цей час не передбачуваний.
Тег сценарію defer
чекає, поки буде виконаний весь аналізатор, а потім запускає всі скрипти, позначені defer
в тому порядку, в якому вони зустрічалися. Це дозволяє позначити кілька сценаріїв, які залежать один від одного як defer
. Усі вони будуть відкладені, поки не буде виконано аналіз документа, але вони будуть виконуватись у порядку, з яким вони стикалися, зберігаючи свої залежності. Я думаю про defer
те, що сценарії випадають у чергу, яка буде оброблена після того, як буде зроблено аналізатор. Технічно браузер може завантажувати сценарії у фоновому режимі в будь-який час, але вони не виконуватимуть чи блокуватимуть аналізатор, поки після того, як буде виконано аналіз, розбирається сторінка та аналізується і виконується будь-які вбудовані сценарії, які не позначені defer
або async
.
Ось цитата з цієї статті:
Сценарії, вставлені в скрипт, виконують асинхронно в IE та WebKit, але синхронно в Opera та Firefox до 4.0.
Відповідна частина HTML5 специфікації (для нових сумісних браузерів) знаходиться тут . Там багато написано про поведінку асинхронізації. Очевидно, ця специфікація не застосовується до старих браузерів (або невідповідних веб-переглядачів), поведінку яких, ймовірно, доведеться перевірити, щоб визначити.
Цитата зі специфікації HTML5:
Тоді необхідно дотримуватися першого з наступних варіантів, який описує ситуацію:
Якщо в елементі є атрибут src, а в елементі є атрибут defer, а елемент позначений як "вставлений аналізатор", а елемент не має атрибута асинхронізації
. Елемент повинен бути доданий до кінця списку сценарії, які будуть виконані після завершення розбору документа, пов'язаного з документом аналізатора, який створив елемент.
Завдання, яке джерело завдань для мережі розміщує у черзі завдань після завершення алгоритму вилучення, повинно встановлювати прапор елемента "готовий до парсера". Аналізатор буде обробляти виконання сценарію.
Якщо в елементі є атрибут src, а елемент позначений як "вставлений аналізатор", а елемент не має атрибута асинхронізації
. Елемент є сценарієм блокування розбору, що очікує на розгляд, в документі аналізатора, який створив елемент. (Одночасно може існувати лише один такий сценарій на Документ.)
Завдання, яке джерело завдань для мережі розміщує у черзі завдань після завершення алгоритму вилучення, повинно встановлювати прапор елемента "готовий до парсера". Аналізатор буде обробляти виконання сценарію.
Якщо в елементі немає атрибуту src, а елемент позначено як "вставлений парсер", а Документ парсерів HTML або XML-аналізатор, який створив елемент сценарію, має таблицю стилів, що блокує сценарії . очікує сценарій блокування синтаксичного розбору документу аналізатора, який створив елемент. (Одночасно може існувати лише один такий сценарій на Документ.)
Встановіть прапор елемента "готовий до парсера". Аналізатор буде обробляти виконання сценарію.
Якщо в елементі є атрибут src, у нього немає атрибута асинхронізації та не встановлено прапор "force-async", елемент повинен бути доданий до кінця списку сценаріїв, які виконуватимуться для того, щоб якнайшвидше пов'язати з елементом «Документ сценарію» в момент запуску алгоритму підготовки сценарію.
Завдання, яке джерело завдань для мережі розміщує у черзі завдань після завершення алгоритму вилучення, має виконати наступні кроки:
Якщо елемент зараз не є першим елементом у списку скриптів, які виконуватимуться для того, щоб якнайшвидше до нього було додано вище, то позначте елемент як готовий, але скасуйте ці кроки, ще не виконуючи сценарій.
Виконання: виконайте блок скриптів, відповідний першому елементу скрипту в цьому списку сценаріїв, який буде виконуватися для того, щоб якнайшвидше.
Видаліть перший елемент із цього списку скриптів, які виконуватимуться якнайшвидше.
Якщо цей список скриптів, які будуть виконані для того, щоб якнайшвидше, все ще не порожній, і перший запис уже позначений як готовий, тоді перейдіть назад до кроку, позначеного виконанням.
Якщо в елементі є атрибут src, елемент повинен бути доданий до набору сценаріїв, який буде виконаний якнайшвидше Документу елемента сценарію в момент запуску алгоритму підготовки сценарію.
Завдання, яке джерело завдань для мережі розміщує у черзі завдань після того, як алгоритм вилучення буде виконаний, повинен виконати блок скриптів, а потім видалити елемент із набору сценаріїв, який буде виконаний якнайшвидше.
В іншому випадку Агент користувача повинен негайно виконати блок скриптів, навіть якщо інші сценарії вже виконуються.
Що з скриптами модуля Javascript type="module"
,?
Тепер у Javascript передбачена підтримка завантаження модуля з таким синтаксисом:
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
Або з src
атрибутом:
<script type="module" src="http://somedomain.com/somescript.mjs">
</script>
Усім сценаріям type="module"
автоматично надається defer
атрибут. Це завантажує їх паралельно (якщо вони не вбудовані в рядки) з іншим завантаженням сторінки, а потім запускає їх у порядку, але після того, як буде виконано аналіз.
Сценаріям модулів також може бути наданий async
атрибут, який запустить сценарії вбудованого модуля якомога швидше, не чекаючи, поки виконаний аналізатор, і не чекаючи запуску async
сценарію в будь-якому конкретному порядку відносно інших сценаріїв.
У цій статті є досить корисна діаграма тимчасової шкали, яка показує отримання та виконання різних комбінацій скриптів, включаючи скрипти модулів, у цій статті: Завантаження модуля Javascript .