Атрибут src: подключение внешних скриптов в JavaScript

Раздел: JavaScript -> подключение скриптов

Подключение внешних скриптов через атрибут src

Самый эффективный способ для большинства современных проектов

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

<script src="js/app.js" defer></script>

Js src (атрибут src тега script)

В таком случае скрипт не блокирует рендеринг, а DOM гарантированно готов к моменту выполнения. Подходит для скриптов, которым нужен весь DOM, и порядок их выполнения важен.

Потенциальные проблемы:

  • Если скрипт использует document.write, то при defer он не сработает (это устаревшая практика).
  • Браузеры, не поддерживающие defer (например, очень старые), проигнорируют атрибут и загрузят скрипт синхронно. Однако для современных сайтов это неактуально.

Как просто подключить внешний скрипт без задержек?

Базовое синхронное подключение. Скрипт загружается и выполняется немедленно, блокируя парсинг HTML до завершения.

<script src="scripts/analytics.js"></script>

как подключить js (как подключить javascript к html)

Используется для критически важных скриптов (например, системы аналитики), которые должны выполниться раньше остального контента. Однако это замедляет загрузку страницы.

Ошибка: если скрипт очень большой, страница будет долго оставаться пустой. Рекомендуется размещать такие скрипты в конце <body>.

Как загрузить скрипт асинхронно, не дожидаясь HTML?

Использование атрибута async. Скрипт загружается параллельно с HTML и выполняется сразу после загрузки, не дожидаясь полного парсинга.

<script src="https://example.com/widget.js" async></script>

Подходит для независимых скриптов (счётчики, реклама), которые не зависят от DOM или других скриптов. Порядок выполнения не гарантируется.

Проблема: если один асинхронный скрипт зависит от другого, они могут выполниться в непредсказуемом порядке. Решение - не использовать async для таких зависимостей.

Как гарантировать выполнение скрипта после загрузки HTML, сохраняя порядок?

Атрибут defer (рассмотрен в основном решении). Альтернатива - разместить скрипт в конце <body> без атрибутов, но это также блокирует рендеринг.

<script src="js/libs.js" defer></script>
<script src="js/init.js" defer></script>

Порядок выполнения соответствует порядку в HTML. Все отложенные скрипты выполняются до события DOMContentLoaded.

Типичная ошибка: использование defer для скриптов, которые должны выполниться как можно раньше (например, полифилы). В таких случаях лучше async или синхронная загрузка.

Как динамически добавить скрипт на страницу после её загрузки?

Создание элемента <script> через JavaScript и добавление его в DOM. Это позволяет загружать скрипты по требованию.

let script = document.createElement('script');
script.src = 'js/chat.js';
script.onload = function() {
  console.log('Чат загружен');
};
document.head.appendChild(script);

Применяется для ленивой загрузки, когда скрипт нужен только после определённого действия пользователя. Скрипты, добавленные таким образом, ведут себя как async по умолчанию (если не указать иное).

Ошибка: если динамический скрипт добавляется до того, как DOM полностью сформирован, может возникнуть конфликт. Решение - использовать DOMContentLoaded или флаги готовности.

Как подключать ES-модули с поддержкой import/export?

Современные браузеры поддерживают атрибут type="module". Скрипты с таким атрибутом автоматически откладываются (как defer) и выполняются в порядке их следования, даже без явного указания.

<script type="module" src="js/main.mjs"></script>

Модули позволяют использовать import и export, а также обеспечивают изоляцию области видимости. Подходит для современных приложений.

Проблема: старые браузеры (IE11) не поддерживают модули. Для них нужна отдельная сборка через <script nomodule> или использование defer с транспиляцией.

Дополнительные атрибуты для src

Атрибут integrity позволяет проверить целостность скрипта через хеш. Атрибут crossorigin используется для скриптов с другого домена, чтобы обрабатывать ошибки или получать доступ к содержимому.

<script src="https://cdn.example.com/lib.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>

Расширенные примеры использования атрибута src

Одновременное использование async и defer

Если указать оба атрибута, то async имеет приоритет над defer для HTML-парсера: скрипт будет загружен асинхронно. Если браузер не поддерживает async (например, очень старые версии), то сработает defer. На практике комбинация не используется, так как поведение неоднозначно.

Пример
<script src="script.js" async defer></script>
В современных браузерах скрипт выполнится как async (сразу после загрузки), в IE9-10 как defer.

Динамическая загрузка с управлением порядком

Допустим, нужно загрузить библиотеку, а затем скрипт, который от неё зависит. Можно установить async=false у динамического скрипта, чтобы он вёл себя синхронно.

Пример
// Загружаем lib.js
let lib = document.createElement('script');
lib.src = 'lib.js';
lib.async = false;
document.head.appendChild(lib);

// Загружаем main.js после lib
let main = document.createElement('script');
main.src = 'main.js';
main.async = false;
document.head.appendChild(main);
Порядок выполнения гарантирован: сначала lib.js, потом main.js, несмотря на асинхронную природу динамических скриптов.

Ленивая загрузка скрипта при появлении в окне просмотра

Используется Intersection Observer для загрузки скрипта, когда элемент становится видимым.

Пример
<div id="chat-placeholder" style="height: 500px;"></div>
<script>
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      let script = document.createElement('script');
      script.src = 'chat.js';
      document.head.appendChild(script);
      observer.disconnect();
    }
  });
  observer.observe(document.getElementById('chat-placeholder'));
</script>

Подключение модуля с запасным вариантом для старых браузеров

Используется комбинация type="module" и <script nomodule>.

Пример
<script type="module" src="modern.js"></script>
<script nomodule src="legacy.js" defer></script>
Браузеры, поддерживающие модули, загрузят modern.js и проигнорируют nomodule. Старые - наоборот, загрузят legacy.js.

Загрузка скрипта с проверкой целостности (integrity)

Атрибут integrity содержит хеш содержимого файла. Браузер проверяет, что загруженный файл соответствует хешу, предотвращая подмену.

Пример
<script src="bootstrap.bundle.min.js"
        integrity="sha384-..."
        crossorigin="anonymous"></script>

Если хеш не совпадает, скрипт не выполнится, и в консоли появится ошибка. Хеш можно получить через инструменты поставщика (например, CDN) или вычислить заранее.

Использование importmap для разрешения модулей

Атрибут src в сочетании с type="importmap" позволяет переопределять URL модулей.

Пример
<script type="importmap">
{
  "imports": {
    "lodash": "/node_modules/lodash-es/lodash.js"
  }
}
</script>
<script type="module">
  import _ from 'lodash';
  console.log(_.add(1, 2));
</script>

атрибут src тега script - comments

En
Js src (javascript)