Как загружать и оптимизировать скрипты

Скрипты в макетах (Layout)

Для загрузки стороннего скрипта для нескольких маршрутов импортируйте next/script и включите скрипт непосредственно в ваш компонент макета:

import Script from 'next/script'

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <>
      <section>{children}</section>
      <Script src="https://example.com/script.js" />
    </>
  )
}
import Script from 'next/script'

export default function DashboardLayout({ children }) {
  return (
    <>
      <section>{children}</section>
      <Script src="https://example.com/script.js" />
    </>
  )
}

Сторонний скрипт будет загружен при доступе пользователя к маршруту папки (например, dashboard/page.js) или любому вложенному маршруту (например, dashboard/settings/page.js). Next.js гарантирует, что скрипт загрузится только один раз, даже если пользователь переходит между несколькими маршрутами в одном макете.

Скрипты приложения

Для загрузки стороннего скрипта для всех маршрутов импортируйте next/script и включите скрипт непосредственно в корневой макет:

import Script from 'next/script'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
      <Script src="https://example.com/script.js" />
    </html>
  )
}
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <Script src="https://example.com/script.js" />
    </html>
  )
}

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

Рекомендация: Мы рекомендуем включать сторонние скрипты только на конкретных страницах или в макетах, чтобы минимизировать влияние на производительность.

Стратегии загрузки

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

  • beforeInteractive: Загружает скрипт до любого кода Next.js и до гидратации страницы.
  • afterInteractive: (по умолчанию) Загружает скрипт рано, но после некоторой гидратации страницы.
  • lazyOnload: Загружает скрипт позже, во время простоя браузера.
  • worker: (экспериментально) Загружает скрипт в веб-воркере.

Обратитесь к документации next/script для получения подробной информации о каждой стратегии и случаях их использования.

Выгрузка скриптов в веб-воркер (экспериментально)

Предупреждение: Стратегия worker пока нестабильна и не работает с App Router. Используйте с осторожностью.

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

Эта стратегия все еще экспериментальная и может использоваться только если флаг nextScriptWorkers включен в next.config.js:

next.config.js
module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}

Затем запустите next (обычно npm run dev или yarn dev), и Next.js проведет вас через установку необходимых пакетов для завершения настройки:

Terminal
npm run dev

Вы увидите инструкции типа: Установите Partytown, выполнив npm install @builder.io/partytown

После завершения настройки, указание strategy="worker" автоматически инициализирует Partytown в вашем приложении и выгрузит скрипт в веб-воркер.

import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}
import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}

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

Встроенные скрипты

Встроенные скрипты, или скрипты, не загружаемые из внешнего файла, также поддерживаются компонентом Script. Они могут быть написаны путем размещения JavaScript в фигурных скобках:

<Script id="show-banner">
  {`document.getElementById('banner').classList.remove('hidden')`}
</Script>

Или с помощью свойства dangerouslySetInnerHTML:

<Script
  id="show-banner"
  dangerouslySetInnerHTML={{
    __html: `document.getElementById('banner').classList.remove('hidden')`,
  }}
/>

Предупреждение: Для встроенных скриптов необходимо указать свойство id, чтобы Next.js мог отслеживать и оптимизировать скрипт.

Выполнение дополнительного кода

Обработчики событий могут использоваться с компонентом Script для выполнения дополнительного кода после определенного события:

  • onLoad: Выполняет код после завершения загрузки скрипта.
  • onReady: Выполняет код после завершения загрузки скрипта и при каждом монтировании компонента.
  • onError: Выполняет код, если скрипт не загрузился.

Эти обработчики будут работать только тогда, когда next/script импортирован и используется внутри Клиентского компонента, где "use client" указан в первой строке кода:

'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onLoad={() => {
          console.log('Script has loaded')
        }}
      />
    </>
  )
}
'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onLoad={() => {
          console.log('Script has loaded')
        }}
      />
    </>
  )
}

Обратитесь к документации next/script для получения подробной информации о каждом обработчике событий и примеров.

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

Существует множество DOM-атрибутов, которые могут быть назначены элементу <script> и не используются компонентом Script, например nonce или пользовательские data-атрибуты. Включение любых дополнительных атрибутов автоматически перенаправит их в финальный оптимизированный элемент <script>, который включается в HTML.

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        id="example-script"
        nonce="XUENAJFW"
        data-test="script"
      />
    </>
  )
}
import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        id="example-script"
        nonce="XUENAJFW"
        data-test="script"
      />
    </>
  )
}