Узнайте, как работает компонент Script в Next.js, который позволяет оптимизировать загрузку сторонних скриптов.
Около 45 % запросов от сайтов, которые показываются на мобильных устройствах и компьютерах, – это сторонние запросы, 33 % из которых являются скриптами. Размер, задержка и загрузка сторонних скриптов могут значительно повлиять на производительность сайта. Компонент Next.js Script поставляется со встроенными рекомендациями и настройками по умолчанию, которые помогают разработчикам внедрять сторонние скрипты в свои приложения, одновременно решая потенциальные проблемы производительности.
Сторонние скрипты и их влияние на производительность
Сторонние скрипты позволяют веб-разработчикам использовать существующие решения для реализации общих функций и сокращения времени разработки. Но создатели этих скриптов обычно не заинтересованы в том, чтобы учитывать влияние на производительность сайта, на котором они используются. Кроме того, эти скрипты представляют собой "черный ящик" для разработчиков, которые их используют.
Скрипты составляют значительную часть сторонних байтов, скачиваемых сайтами по разным категориям сторонних запросов. По умолчанию браузер определяет приоритет скриптов в зависимости от их расположения в документе. Это может задерживать обнаружение или выполнение скриптов, важных для удобства пользователей.
Сторонние библиотеки, необходимые для макета, должны загружаться на раннем этапе, чтобы страница могла отрисовываться. Сторонние ресурсы, которые не требуются для начальной отрисовки, должны загружаться позже, чтобы не блокировать другие процессы в основном потоке. В Lighthouse есть две проверки, которые позволяют выявить скрипты, блокирующие отрисовку или основной поток.
Важно учитывать последовательность загрузки ресурсов на странице, чтобы критически важные ресурсы не задерживались, а некритичные ресурсы не блокировали критически важные.
Существуют рекомендации по снижению влияния стороннего кода, но не все знают, как их применять. Это может быть сложно по следующим причинам:
- В среднем на сайтах используется от 21 до 23 сторонних ресурсов, включая скрипты, как в мобильной, так и в десктопной версии. Рекомендации по использованию могут различаться.
- Реализация многих сторонних ресурсов может отличаться в зависимости от того, используется ли определенный фреймворк или библиотека пользовательского интерфейса.
- Новые сторонние библиотеки появляются часто.
- Разные бизнес-требования, связанные с одним и тем же сторонним SDK, затрудняют его стандартизацию.
Особое внимание к сторонним скриптам
В рамках сотрудничества с веб-фреймворками и инструментами с ПО с открытым исходным кодом команда Aurora предоставляет надежные настройки по умолчанию и специализированные инструменты, которые помогают улучшать производительность, доступность, безопасность и готовность к работе на мобильных устройствах. В 2021 году мы сосредоточились на том, чтобы помочь разработчикам фреймворков улучшить удобство использования и показатели Core Web Vitals.
Одним из самых важных шагов на пути к повышению производительности фреймворка стало исследование идеальной последовательности загрузки сторонних скриптов в Next.js. Фреймворки, такие как Next.js, предоставляют полезные настройки по умолчанию и функции, которые помогают разработчикам эффективно загружать ресурсы, в том числе сторонние. Мы изучили обширные данные HTTP Archive и Lighthouse, чтобы выяснить, какие сторонние ресурсы чаще всего блокируют отрисовку в разных фреймворках.
Чтобы решить проблему с блокировкой основного потока сторонними скриптами, используемыми в приложении, мы создали компонент Script. Компонент содержит функции упорядочивания, которые позволяют разработчикам лучше контролировать загрузку сторонних скриптов.
Как упорядочить сторонние скрипты без компонента фреймворка
В рекомендациях по снижению влияния скриптов, блокирующих отрисовку, предлагаются следующие методы эффективной загрузки и упорядочивания сторонних скриптов:
Используйте атрибут
asyncилиdeferс тегами<script>, чтобы браузер загружал второстепенные сторонние скрипты, не блокируя синтаксический анализатор документа. Скрипты, которые не требуются для начальной загрузки страницы или первого взаимодействия пользователя, могут считаться некритичными.<script src="https://example.com/script1.js" defer></script> <script src="https://example.com/script2.js" async></script>Установите ранние подключения к необходимым источникам с помощью предварительного подключения и предварительной выборки DNS. Это позволяет начать скачивание критически важных скриптов раньше.
<head> <link rel="preconnect" href="http://PreconnThis.com"> <link rel="dns-prefetch" href="http://PrefetchThis.com"> </head>Используйте отложенную загрузку сторонних ресурсов и встроенных объектов после того, как загрузится основной контент страницы или когда пользователь прокрутит страницу до места, где они расположены.
Компонент Next.js Script
Компонент Next.js Script реализует описанные выше методы упорядочивания скриптов и предоставляет разработчикам шаблон для определения стратегии загрузки. После того как вы укажете подходящую стратегию, он будет загружаться оптимальным образом, не блокируя другие важные ресурсы.
Компонент Script основан на HTML-теге <script> и позволяет задавать приоритет загрузки сторонних скриптов с помощью атрибута strategy.
// Example for beforeInteractive:
<Script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />
// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />
// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />
Атрибут strategy может принимать три значения.
beforeInteractive. Этот вариант можно использовать для критически важных скриптов, которые должны выполняться до того, как страница станет интерактивной. Next.js гарантирует, что такие скрипты будут вставлены в исходный HTML-код на сервере и выполнены до другого JavaScript, упакованного самостоятельно. Этот подход хорошо подходит для управления согласием, скриптов обнаружения ботов и вспомогательных библиотек, необходимых для отрисовки критически важного контента.afterInteractive– стратегия по умолчанию, которая эквивалентна загрузке скрипта с атрибутом defer. Этот атрибут следует использовать для скриптов, которые браузер может запустить после того, как страница станет интерактивной, например для скриптов аналитики. Next.js внедряет эти скрипты на клиентской стороне, и они выполняются после гидратации страницы. Таким образом, если не указано иное, все сторонние скрипты, определенные с помощью компонента Script, откладываются Next.js, что обеспечивает надежное значение по умолчанию.lazyOnload– этот вариант можно использовать для отложенной загрузки скриптов с низким приоритетом, когда браузер бездействует. Функции, которые обеспечивают такие скрипты, не требуются сразу после того, как страница становится интерактивной. Примером могут служить плагины чата или социальных сетей.
Разработчики могут указать в Next.js, как приложение использует скрипт, выбрав стратегию. Это позволяет фреймворку применять оптимизацию и рекомендации по загрузке скрипта, обеспечивая наилучшую последовательность загрузки.
С помощью компонента Script разработчики могут размещать сторонние скрипты в любом месте приложения для сторонних ресурсов с поздней загрузкой и на уровне документа для критически важных скриптов. Это означает, что компонент Script может находиться в одном месте с компонентом, использующим скрипт. После гидратации скрипт будет вставлен в заголовок изначально отрисованного документа или в нижнюю часть тела, в зависимости от используемой стратегии.
Оценка влияния
Мы использовали шаблоны для коммерческого приложения и блога Next.js, чтобы создать два демонстрационных приложения, которые помогли измерить влияние сторонних скриптов. Сторонние сервисы, которые часто используются для Google Менеджера тегов и встраивания социальных сетей, сначала были добавлены на страницы этих приложений напрямую, а затем – через компонент Script. Затем мы сравнили эффективность этих страниц в WebPageTest.
Сторонние скрипты в коммерческом приложении Next.js
В шаблон приложения для электронной торговли были добавлены сторонние скрипты, как показано ниже.
На изображении ниже показано, как выглядят обе версии стартового набора Next.js для электронной торговли. Как видно, при включенном компоненте Script с правильной стратегией загрузки LCP происходит почти на секунду раньше.
Сторонние скрипты в блоге Next.js
Сторонние скрипты были добавлены в демонстрационное приложение блога, как показано ниже.
| До | После |
|---|---|
| Google Менеджер тегов с асинхронной загрузкой | Компонент Script со стратегией lazyonload для каждого из четырех скриптов |
| Кнопка "Читать" в Твиттере с асинхронным кодом | |
| Кнопка "Подписаться" без атрибутов async и defer | |
| Кнопка "Подписаться" в LinkedIn без async или defer |
Как показано в видео, первая отрисовка контента (FCP) происходит через 0,9 секунды на странице без компонента Script и через 0,4 секунды с компонентом Script.
Что дальше
Хотя стратегии afterInteractive и lazyOnload позволяют эффективно управлять скриптами, блокирующими отрисовку, мы также изучаем другие варианты, которые могут повысить полезность компонента Script.
Использование объектов Web Worker
Веб-воркеры позволяют запускать независимые скрипты в фоновых потоках, освобождая основной поток для обработки задач пользовательского интерфейса и повышая производительность. Веб-воркеры лучше всего подходят для разгрузки основного потока от обработки JavaScript, а не от работы с пользовательским интерфейсом. Скрипты, используемые для поддержки пользователей или маркетинга, которые обычно не взаимодействуют с пользовательским интерфейсом, могут быть хорошими кандидатами для выполнения в фоновом потоке. Чтобы изолировать такие скрипты в веб-воркере, можно использовать стороннюю библиотеку PartyTown.
При текущей реализации компонента скрипта Next.js мы рекомендуем отложить выполнение этих скриптов в основном потоке, задав стратегию afterInteractive или lazyOnload. В будущем мы планируем добавить новую стратегию 'worker', которая позволит Next.js использовать PartyTown или другое решение для запуска скриптов в веб-воркерах. Мы будем рады получить от разработчиков комментарии к этому RFC.
Минимизация CLS
Сторонние встроенные объекты, такие как реклама, видео или ленты социальных сетей, могут вызывать сдвиги макета при отложенной загрузке. Это негативно сказывается на удобстве использования и показателе Cumulative Layout Shift (CLS). Чтобы минимизировать CLS, укажите размер контейнера, в который будет загружаться встроенный контент.
Компонент Script может использоваться для загрузки встроенных объектов, которые могут вызывать смещение макета. Мы рассматриваем возможность добавить в него настройки, которые помогут снизить CLS. Это можно сделать в самом компоненте скрипта или в сопутствующем компоненте.
Компоненты-обертки
Синтаксис и стратегия загрузки популярных сторонних скриптов, таких как Google Аналитика или Google Менеджер тегов, обычно фиксированы. Их можно дополнительно инкапсулировать в отдельные компоненты-оболочки для каждого типа скрипта. Разработчикам будет доступен только минимальный набор атрибутов, относящихся к приложению (например, идентификатор отслеживания). Компоненты-оболочки помогут разработчикам:
- Это упрощает добавление популярных тегов script.
- Обеспечение того, чтобы фреймворк использовал наиболее оптимальную стратегию.
Заключение
Сторонние скрипты обычно создаются для добавления определенных функций на сайт. Чтобы снизить влияние некритичных скриптов, рекомендуем отложить их выполнение. По умолчанию это делает компонент Script в Next.js. Разработчики могут быть уверены, что включенные скрипты не будут задерживать критически важные функции, если они явно не применят стратегию beforeInteractive. Разработчики других фреймворков могут добавить в них аналогичные функции. Мы активно изучаем возможность создания аналогичного компонента совместно с командой Nuxt.js. Мы также надеемся, что отзывы пользователей помогут нам улучшить компонент скрипта и расширить сферу его применения.
Благодарности
Благодарим Кару Эриксон (Kara Erickson), Яникласа Ральфа (Janicklas Ralph), Кэти Хемпениус (Katie Hempenius), Филипа Уолтона (Philip Walton), Джереми Вагнера (Jeremy Wagner) и Эдди Османи (Addy Osmani) за отзывы об этой статье.