Скрипты JavaScript могут замедлить сайт так, что пользователи уйдут, не дождавшись загрузки. Но не всё так плохо: есть проверенные приёмы, которые помогут ускорить загрузку и улучшить пользовательский опыт. В этой статье разберём, как оптимизировать загрузку скриптов, чтобы ваш сайт летал.

Digital-студия WNDER

Почему JavaScript тормозит загрузку

Когда браузер встречает тег <script>, он останавливает построение DOM, загружает скрипт и выполняет его. Если скриптов много или они тяжёлые, страница белеет и ждёт. Это как если бы вы читали книгу, а на каждой странице кто-то вырывал лист и заставлял ждать, пока его перепишут.

Особенно плохо, когда скрипты находятся в <head> без атрибутов async или defer. Они блокируют отрисовку. Пользователь видит пустой экран, пока не загрузятся все скрипты.

Атрибуты async и defer: в чём разница

Два простых атрибута могут сильно улучшить ситуацию. async говорит браузеру: «Загружай скрипт параллельно, но выполни, как только загрузишь, не дожидаясь порядка». defer говорит: «Загружай параллельно, но выполни после построения DOM, сохраняя порядок».

Вот пример подключения скриптов с этими атрибутами:

<script src="script1.js" async></script>
<script src="script2.js" defer></script>

Когда что использовать? async подходит для независимых скриптов (например, счётчики). defer — для скриптов, которые зависят от DOM или других скриптов.

Правило: Всегда добавляйте defer к скриптам в <head>, если они не критичны для отрисовки. Это ускорит первую отрисовку.

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

Иногда нужно загрузить скрипт только при определённом условии. Например, при клике на кнопку. Тогда можно создать тег <script> динамически через JavaScript. Это позволяет не грузить лишнее сразу.

function loadScript(src) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.onload = () => resolve();
    script.onerror = () => reject(new Error('Ошибка загрузки ' + src));
    document.head.append(script);
  });
}

// Использование
loadScript('/js/chat-widget.js')
  .then(() => console.log('Скрипт загружен'))
  .catch(error => console.error(error));

Такой подход даёт полный контроль над загрузкой. Можно загружать скрипты по требованию, экономить трафик и ускорять начальную загрузку.

Оптимизация размера и сжатие

Чем меньше скрипт, тем быстрее он загрузится. Используйте минификацию (удаление пробелов и комментариев) и сжатие (gzip или brotli). Современные сборщики, такие как Webpack или Vite, делают это автоматически.

Также важно разделять код на чанки (куски) и загружать только нужное. Например, с помощью динамического import():

// Вместо статического импорта
import { heavyFunction } from './heavyModule.js';

// Используйте динамический импорт
button.addEventListener('click', async () => {
  const { heavyFunction } = await import('./heavyModule.js');
  heavyFunction();
});

Этот приём называется «ленивая загрузка» (lazy loading). Он позволяет не грузить тяжёлые модули, пока они не понадобятся.

Предзагрузка и предподключение

Можно подсказать браузеру, какие ресурсы понадобятся скоро. Для этого есть <link rel="preload"> и <link rel="prefetch">. Первый загружает ресурс с высоким приоритетом, второй — с низким (для будущих навигаций).

<link rel="preload" href="/js/critical.js" as="script">
<link rel="prefetch" href="/js/next-page.js" as="script">

Но не злоупотребляйте: предзагрузка конкурирует за пропускную способность. Используйте только для критичных ресурсов.

Лайфхак: Если у вас много скриптов, объедините их в один файл (бандл). Это уменьшит количество запросов. Но не переусердствуйте: иногда лучше разделить код на чанки для кэширования.

Сравнение методов загрузки

В таблице ниже — краткая шпаргалка по методам и их влиянию на загрузку.

Метод Когда использовать Плюсы Минусы
Обычный <script> Критичный код, который должен выполниться до DOM Простота Блокирует парсинг
async Независимые скрипты (аналитика) Не блокирует, выполняется сразу после загрузки Порядок не гарантирован
defer Скрипты, зависящие от DOM или других скриптов Не блокирует, сохраняет порядок Выполняется после DOM
Динамическая загрузка По требованию (ленивая) Гибкость, экономия трафика Сложнее отлаживать

Что в итоге

Оптимизация загрузки JavaScript — это не магия, а набор простых действий. Используйте defer и async, динамически подгружайте скрипты, сжимайте код и применяйте предзагрузку. Эти методы помогут вашему сайту загружаться быстрее, а пользователям — оставаться довольными.

Помните: быстрый сайт — это не только технологии, но и забота о пользователе. Начните с малого: проверьте, какие скрипты блокируют загрузку, и примените хотя бы defer. Результат не заставит себя ждать.

Студия WNDER