Загрузка стороннего кода JavaScript

Arthur Evans

Если вы оптимизировали код, но сайт все равно загружается слишком медленно, возможно, проблема в сторонних скриптах.

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

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

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

Что такое сторонние скрипты?

Сторонний код JavaScript – это скрипты, которые можно встраивать в любой сайт непосредственно от стороннего поставщика. Примеры:

  • Кнопки для публикации в соцсетях (Facebook, X, LinkedIn, Mastodon)

  • Встроенные видеопроигрыватели (YouTube, Vimeo)

  • Рекламные окна iframe

  • Скрипты для аналитики и показателей

  • Скрипты для A/B-тестирования

  • Вспомогательные библиотеки, например для форматирования дат, анимации или функциональные библиотеки.

Пример встроенного видео YouTube
Пример встроенного видео YouTube, которое можно добавить на страницу с помощью приведенного ниже кода.
<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/mo8thg5XGV0"
  frameborder="0"
  allow="autoplay; encrypted-media"
  allowfullscreen
>
</iframe>

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

  • Отправка слишком большого количества сетевых запросов на несколько серверов. Чем больше запросов должен сделать сайт, тем дольше он может загружаться.

  • Отправка слишком большого объема кода JavaScript, который перегружает основной поток. Слишком много JavaScript может заблокировать построение DOM, что задерживает рендеринг страницы. Синтаксический анализ и выполнение скриптов, требующие высокой производительности процессора, могут замедлить взаимодействие с пользователем и привести к разрядке батареи.

  • Отправка больших неоптимизированных графических файлов или видео может привести к расходу трафика и средств пользователей.

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

  • Недостаточное кеширование HTTP, из-за чего браузеру приходится отправлять больше сетевых запросов для получения ресурсов.

  • Недостаточное сжатие на сервере приводит к медленной загрузке ресурсов.

  • Блокировка показа контента до завершения обработки. Это также может быть верно для асинхронных скриптов A/B-тестирования.

  • Использование устаревших API, которые могут ухудшить взаимодействие с пользователем, например document.write().

  • Слишком много элементов DOM или сложные селекторы CSS.

  • Включение нескольких сторонних встраиваний может привести к тому, что несколько фреймворков и библиотек будут загружены несколько раз, что приведет к потере ресурсов и усугубит существующие проблемы с производительностью.

  • Сторонние скрипты часто используют методы встраивания, которые могут блокировать window.onload, если их серверы отвечают медленно, даже если встраивание использует async или defer.

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

Как определить сторонний скрипт на странице?

Первый шаг к оптимизации сторонних скриптов – определить, какие из них используются на вашем сайте и как они влияют на его производительность. Чтобы выявить скрипты, замедляющие работу сайта, рекомендуем использовать бесплатные инструменты для теста скорости, такие как инструменты разработчика Chrome, PageSpeed Insights и WebPageTest. Эти инструменты отображают подробную диагностическую информацию, которая может сказать вам, сколько сторонних скриптов использует ваш сайт и какие из них занимают больше всего времени для выполнения.

Каскадная диаграмма WebPageTest может показать, как на производительность влияет использование тяжелых сторонних скриптов. На изображении ниже из статьи Tags Gone Wild показана диаграмма сетевых запросов, необходимых для загрузки основного контента сайта, в отличие от скриптов отслеживания и маркетинга.

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

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

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

Как оценить влияние стороннего скрипта на страницу?

Если вы обнаружили скрипт, вызывающий проблемы, выясните, что он делает и нужен ли он для работы сайта. При необходимости проведите A/B-тестирование, чтобы найти баланс между ценностью функции и ее влиянием на ключевые показатели вовлеченности пользователей или эффективности.

Проверка времени загрузки в Lighthouse

Проверка времени загрузки JavaScript в Lighthouse позволяет выявить скрипты, на обработку, компиляцию или оценку которых уходит много времени. Это поможет вам выявить сторонние скрипты, которые сильно нагружают процессор.

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

Проверка сетевой нагрузки в Lighthouse

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

Lighthouse показывает поддержку больших сетевых полезных нагрузок
Проверка полезной нагрузки сети показывает, какие сетевые запросы занимают больше всего времени и извлекают больше всего данных.

Блокировка сетевых запросов в инструментах разработчика Chrome

Инструменты разработчика Chrome позволяют увидеть, как ведет себя страница, когда определенный скрипт, таблица стилей или другой ресурс недоступны. Это делается с помощью блокировки сетевых запросов – функции, которая помогает оценить влияние удаления отдельных сторонних ресурсов с вашей страницы.

Чтобы включить блокировку запросов, нажмите правой кнопкой мыши на любой запрос на панели "Сеть" и выберите Заблокировать URL запроса. После этого на панели инструментов разработчика появится вкладка, на которой можно управлять заблокированными запросами.

Как заблокировать URL запросов на панели &quot;Сеть&quot; в Инструментах разработчика
Блокируйте отдельные сетевые запросы, чтобы посмотреть, как страница ведет себя без них.

Панель "Производительность" в инструментах разработчика Chrome

Панель "Производительность" в инструментах разработчика Chrome помогает выявлять проблемы с производительностью страниц.

  1. Нажмите Запись.
  2. Загрузите страницу. В DevTools появится каскадная диаграмма, показывающая, на что уходит время загрузки сайта.
  3. Перейдите к разделу Снизу вверх в нижней части панели "Производительность".
  4. Нажмите Group by product (Сгруппировать по продукту) и отсортируйте сторонние скрипты по времени загрузки.
Панель &quot;Производительность&quot; в инструментах разработчика, на которой показано представление &quot;Снизу вверх&quot; со сторонними продуктами
Сторонние скрипты, отсортированные по продукту, начиная с самого долгого времени загрузки.

Подробнее о том, как анализировать производительность загрузки страниц с помощью инструментов разработчика Chrome…

Ниже приведен рекомендуемый рабочий процесс для измерения влияния сторонних скриптов:

  1. Используйте панель "Сеть", чтобы измерить время загрузки страницы.
  2. Заблокируйте URL или домены, на которых размещены сторонние скрипты, вызывающие проблемы. О том, как выявить такие скрипты, читайте в статье Панель "Производительность" в Инструментах разработчика Chrome.
  3. Обновите страницу и снова измерьте время загрузки.
    • Чтобы получить более точные данные, измерьте время загрузки не менее трех раз. Это связано с тем, что некоторые сторонние скрипты при каждой загрузке страницы извлекают разные ресурсы. Чтобы упростить эту задачу, на панели "Производительность" в инструментах разработчика можно создавать несколько записей.

Как оценить влияние сторонних скриптов с помощью WebPageTest

В WebPageTest можно заблокировать загрузку отдельных запросов, чтобы оценить их влияние. Для этого перейдите в Advanced Settings (Расширенные настройки) > Block (Заблокировать). С помощью этой функции можно указать список доменов, которые нужно заблокировать, например рекламные домены.

WebPageTest advanced settings (Расширенные настройки WebPageTest) < Block (Блокировка).
Показывает текстовое поле, в котором можно указать домены для блокировки.
Укажите домены, которые нужно заблокировать.

Рекомендуем использовать эту функцию следующим образом:

  1. Протестируйте страницу, не блокируя сторонние файлы cookie.
  2. Повторите тест, заблокировав некоторые сторонние файлы cookie.
  3. Выберите два результата из истории тестирования.
  4. Нажмите Сравнить.
WebPageTest, показывающий опцию сравнения,
позволяющую сравнить два отчета
Выберите результаты тестирования нагрузки, которые нужно сравнить.

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

Раскадровка WebPageTest, показывающая влияние загрузки сайта с отключенными сторонними файлами cookie и без них
Влияние блокировки сторонних ресурсов. Источник: Using WebPageTest To Measure The Impact Of Third-Party Tags (Использование WebPageTest для оценки влияния сторонних тегов), автор Энди Дэвис (Andy Davies).

WebPageTest также поддерживает две команды, которые работают на уровне DNS и блокируют домены:

  • blockDomains принимает список доменов, которые нужно заблокировать.
  • blockDomainsExcept принимает список доменов и блокирует все, что не входит в этот список.

В WebPageTest также есть вкладка единой точки отказа (SPOF), которая позволяет симулировать тайм-аут или полный сбой загрузки ресурса. В отличие от блокировки домена, SPOF медленно завершает работу по тайм-ауту, что может быть полезно для тестирования поведения ваших страниц, когда сторонние сервисы находятся под большой нагрузкой или временно недоступны.

Расширенные настройки WebPageTest > SPOF > хосты, которые нужно отключить
Используйте функцию тестирования единой точки отказа, чтобы смоделировать сбой указанных доменов.

Как выявлять ресурсоемкие окна iframe с помощью длительных задач

Если скрипты в сторонних окнах iframe выполняются долго, они могут блокировать основной поток и задерживать другие задачи. Из-за этих длительных задач обработчики событий могут работать медленно, а кадры – пропускаться, что ухудшает взаимодействие с пользователем.

Чтобы выявлять длительные задачи для мониторинга реальных пользователей (RUM), используйте API JavaScript PerformanceObserver для отслеживания записей longtask. Эти записи содержат свойство атрибуции, которое можно использовать для определения контекста фрейма, вызвавшего длительную задачу.

Следующий код регистрирует записи longtask в консоли, включая одну для "дорогого" iframe:

<script>
  const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // Attribution entry including "containerSrc":"https://example.com"
      console.log(JSON.stringify(entry.attribution));
    }
  });

  observer.observe({entryTypes: ['longtask']});
</script>

<!-- Imagine this is an iframe with expensive long tasks -->
<iframe src="https://example.com"></iframe>

Подробнее о мониторинге длительных задач…

Как эффективно загружать сторонние скрипты?

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

  • Загружайте скрипт с атрибутом async или defer, чтобы не блокировать синтаксический анализ документа.
  • Если сторонний сервер работает медленно, разместите скрипт на своем сервере.
  • Если скрипт не приносит очевидной пользы, удалите его.
  • Используйте подсказки ресурсов, например <link rel=preconnect> или <link rel=dns-prefetch>, чтобы выполнить DNS-запрос для доменов, на которых размещены сторонние скрипты.

Используйте async или defer

Выполнение JavaScript блокирует синтаксический анализатор. Когда браузер обнаруживает скрипт, он должен приостановить построение DOM, передать скрипт в движок JavaScript и разрешить его выполнение, прежде чем продолжить построение DOM.

Атрибуты async и defer меняют это поведение следующим образом:

  • async заставляет браузер асинхронно скачивать скрипт, продолжая анализировать HTML-документ. Когда скрипт скачан, синтаксический анализ блокируется на время его выполнения.

  • defer заставляет браузер асинхронно скачивать скрипт, продолжая анализировать HTML-документ, а затем ждать запуска скрипта до завершения анализа документа.

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

Если для вас важна производительность, рекомендуем добавлять асинхронные скрипты после загрузки основного контента страницы. Мы не рекомендуем использовать async для важных библиотек, таких как jQuery.

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

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

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

Используйте подсказки ресурсов, чтобы сократить время настройки подключения

Установление соединений со сторонними источниками может занять много времени, особенно в медленных сетях, поскольку сетевые запросы имеют несколько сложных компонентов, включая DNS-запросы и перенаправления. Вы можете использовать подсказки ресурсов, например , чтобы выполнять DNS-запросы для доменов, на которых размещены сторонние скрипты, на раннем этапе загрузки страницы. Это позволит ускорить обработку остальной части сетевого запроса.

<link rel="dns-prefetch" href="http://example.com" />

Если сторонний домен, к которому вы подключаетесь, использует HTTPS, вы также можете использовать , который выполняет DNS-запросы, а также разрешает TCP-подключения туда и обратно и обрабатывает согласования TLS. Эти шаги могут быть очень медленными, поскольку они включают проверку SSL-сертификатов, поэтому предварительное подключение может значительно сократить время загрузки.

<link rel="preconnect" href="https://cdn.example.com" />

Изоляция скриптов с помощью iframe

Если вы загружаете сторонний скрипт непосредственно в iframe, он не блокирует выполнение основной страницы. AMP использует этот подход, чтобы исключить JavaScript из критического пути. Обратите внимание, что этот подход по-прежнему блокирует событие onload, поэтому старайтесь не привязывать к нему критически важные функции.onload

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

Размещайте сторонние скрипты на собственном сервере

Если вы хотите лучше контролировать загрузку критически важного скрипта, например сократить время DNS или улучшить заголовки кеширования HTTP, вы можете разместить его у себя.

Однако у этого подхода есть свои недостатки, особенно когда речь идет об обновлении скриптов. Скрипты, размещенные на собственных серверах, не будут автоматически обновляться при изменении API или исправлении уязвимостей. Это может привести к потере дохода или проблемам с безопасностью, пока вы не обновите скрипт вручную.

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

A/B-тестирование на небольших выборках пользователей

A/B-тестирование (или сплит-тестирование) – это метод экспериментирования с двумя версиями страницы для анализа пользовательского опыта и поведения. Разные версии страницы показываются разным группам посетителей сайта, а затем на основе аналитики определяется, какая версия обеспечивает более высокий коэффициент конверсии.

Однако по своей природе A/B-тестирование задерживает отрисовку, чтобы определить, какой эксперимент должен быть активным. JavaScript часто используется для проверки того, относится ли пользователь к эксперименту A/B-тестирования, и включения правильного варианта. Это может ухудшить работу сайта даже для пользователей, не участвующих в эксперименте.

Чтобы ускорить отрисовку страниц, рекомендуем отправлять скрипты A/B-тестирования меньшей выборке пользователей и выполнять код, определяющий, какую версию страницы показывать, на стороне сервера.

Отложенная загрузка сторонних ресурсов

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

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

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

В официальной документации DoubleClick есть инструкции по настройке отложенной загрузки объявлений.

Эффективная отложенная загрузка с помощью Intersection Observer

Раньше методы, позволяющие определить, виден ли элемент в области просмотра для целей отложенной загрузки, часто приводили к ошибкам и замедляли работу браузера. Эти неэффективные методы часто прослушивают события scroll или resize, а затем используют API DOM, такие как getBoundingClientRect(), чтобы рассчитать, где элементы находятся относительно области просмотра.

IntersectionObserver – это API браузера, который позволяет администраторам страниц эффективно определять, когда наблюдаемый элемент входит в область просмотра браузера или покидает ее. В LazySizes также есть необязательная поддержка IntersectionObserver.

Аналитика отложенной загрузки

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

В записи блога Фила Уолтона Настройка Google Аналитики, которую я использую на каждом созданном мной сайте описана одна из таких стратегий для Google Аналитики.

Безопасная загрузка сторонних скриптов

В этом разделе приведены рекомендации по максимально безопасной загрузке сторонних скриптов.

Избегать document.write()

Сторонние скрипты, особенно для старых сервисов, иногда используют document.write() для внедрения и загрузки скриптов. Это проблема, поскольку document.write() ведет себя непоследовательно, а его сбои трудно отлаживать.

Чтобы устранить проблемы с document.write(), не используйте этот метод. В Chrome 53 и более поздних версиях инструменты разработчика Chrome регистрируют в консоли предупреждения о проблемах, связанных с использованием document.write():

Предупреждения в консоли инструментов разработчика, указывающие на нарушения, связанные со сторонним встроенным кодом, в котором используется document.write()
Использование флагов document.write() в инструментах разработчика Chrome.

Если вы получили эту ошибку, проверьте, используется ли на вашем сайте document.write(). Для этого посмотрите HTTP-заголовки, отправленные в ваш браузер. Lighthouse также может выделить сторонние скрипты, которые все ещё используют document.write().

Проверка рекомендаций Lighthouse, в которой отмечается использование document.write()
Отчет Lighthouse, в котором показано, какие скрипты используют document.write().

Соблюдайте осторожность при работе с менеджерами тегов

Тег – это фрагмент кода, который позволяет специалистам по цифровому маркетингу собирать данные, настраивать файлы cookie или интегрировать сторонний контент, например виджеты социальных сетей, на сайт. Эти теги добавляют на страницу сетевые запросы, зависимости JavaScript и другие ресурсы, которые могут повлиять на ее производительность. Чем больше тегов вы добавляете, тем сложнее минимизировать это влияние.

Чтобы загрузка страницы была быстрой, рекомендуем использовать Google Менеджер тегов (GTM). Менеджер тегов позволяет развертывать теги асинхронно, чтобы они не блокировали загрузку друг друга, сокращает количество сетевых вызовов, необходимых браузеру для выполнения тегов, и собирает данные тегов в интерфейсе уровня данных.

Риски, связанные с использованием менеджеров тегов

Хотя менеджеры тегов предназначены для ускорения загрузки страниц, при неосторожном использовании они могут замедлить ее следующими способами:

  • Если в Менеджере тегов слишком много тегов и прослушивателей автоматических событий, браузеру приходится отправлять больше сетевых запросов, чем нужно, и код медленнее реагирует на события.
  • Любой пользователь, у которого есть учетные данные и доступ, может добавить код JavaScript в ваш менеджер тегов. Это не только увеличивает количество дорогостоящих сетевых запросов, необходимых для загрузки страницы, но и может привести к проблемам с безопасностью и другим проблемам производительности из-за ненужных скриптов. Чтобы снизить эти риски, мы рекомендуем ограничить доступ к менеджеру тегов.

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

Сторонние скрипты могут вести себя по-разному и неожиданно нарушать работу страницы:

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

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

Стратегии смягчения последствий

Вот несколько масштабных стратегий по минимизации влияния сторонних скриптов на производительность и безопасность вашего сайта:

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

// Given this CSP header Content-Security-Policy: script-src
https://example.com/ // The following third-party script will not be loaded or
executed

<script src="https://not-example.com/js/library.js"></script>

Дополнительные сведения

Чтобы узнать больше об оптимизации стороннего кода JavaScript, рекомендуем ознакомиться со следующими материалами:

Благодарим Кенджи Бахё (Kenji Baheux), Джереми Вагнера (Jeremy Wagner), Пэта Минана (Pat Meenan), Филипа Уолтона (Philip Walton), Джеффа Посника (Jeff Posnick) и Чейни Цая (Cheney Tsai) за отзывы.