Как загружать и оптимизировать скрипты
Скрипты в макетах (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
:
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}
Затем запустите next
(обычно npm run dev
или yarn dev
), и Next.js проведет вас через установку необходимых пакетов для завершения настройки:
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"
/>
</>
)
}