Оптимизация использования памяти
По мере роста приложений и добавления новых функций, они могут требовать больше ресурсов при локальной разработке или создании продакшен-сборок.
Рассмотрим стратегии и техники оптимизации памяти, а также способы решения распространённых проблем с памятью в Next.js.
Уменьшение количества зависимостей
Приложения с большим количеством зависимостей потребляют больше памяти.
Анализатор бандлов (Bundle Analyzer) поможет выявить крупные зависимости в вашем приложении, которые можно удалить для улучшения производительности и снижения потребления памяти.
Использование experimental.webpackMemoryOptimizations
Начиная с версии v15.0.0
, вы можете добавить experimental.webpackMemoryOptimizations: true
в файл next.config.js
, чтобы изменить поведение Webpack, уменьшающее максимальное потребление памяти, но потенциально незначительно увеличивающее время компиляции.
Важно знать: В настоящее время эта функция находится в экспериментальном статусе для тестирования на большем количестве проектов, но считается низкорисковой.
Запуск next build
с --experimental-debug-memory-usage
Начиная с версии 14.2.0
, вы можете запустить next build --experimental-debug-memory-usage
для выполнения сборки в режиме, где Next.js будет непрерывно выводить информацию о потреблении памяти в процессе сборки, такую как использование кучи и статистику сборки мусора. Снимки кучи (heap snapshots) также будут автоматически создаваться при приближении к установленному лимиту памяти.
Важно знать: Эта функция несовместима с опцией Webpack build worker, которая автоматически включается, если у вас нет пользовательской конфигурации Webpack.
Запись профиля кучи
Для поиска проблем с памятью вы можете записать профиль кучи из Node.js и загрузить его в Chrome DevTools для выявления потенциальных источников утечек памяти.
В терминале передайте флаг --heap-prof
в Node.js при запуске сборки Next.js:
node --heap-prof node_modules/next/dist/bin/next build
После завершения сборки Node.js создаст файл .heapprofile
.
В Chrome DevTools откройте вкладку "Memory" и нажмите кнопку "Load Profile" для визуализации файла.
Анализ снимка кучи
Вы можете использовать инструмент инспектора для анализа потребления памяти приложением.
При запуске команд next build
или next dev
добавьте NODE_OPTIONS=--inspect
в начало команды. Это откроет агент инспектора на стандартном порту.
Если вы хотите остановить выполнение до запуска пользовательского кода, используйте --inspect-brk
. Во время работы процесса вы можете подключиться к порту отладки через инструменты вроде Chrome DevTools, чтобы записать и проанализировать снимок кучи для определения удерживаемой памяти.
Начиная с версии 14.2.0
, вы также можете запустить next build
с флагом --experimental-debug-memory-usage
для упрощения создания снимков кучи.
В этом режиме вы можете отправить сигнал SIGUSR2
процессу в любой момент, и процесс создаст снимок кучи.
Снимок кучи сохранится в корне проекта Next.js и может быть загружен в любой анализатор кучи, например Chrome DevTools, для просмотра удерживаемой памяти. Этот режим пока несовместим с Webpack build workers.
Подробнее см. как записывать и анализировать снимки кучи.
Webpack build worker
Webpack build worker позволяет запускать компиляции Webpack в отдельном Node.js воркере, что уменьшает потребление памяти приложением во время сборок.
Эта опция включена по умолчанию, начиная с версии v14.1.0
, если в приложении нет пользовательской конфигурации Webpack.
Если вы используете более старую версию Next.js или имеете пользовательскую конфигурацию Webpack, вы можете включить эту опцию, установив experimental.webpackBuildWorker: true
в файле next.config.js
.
Важно знать: Эта функция может быть несовместима со всеми пользовательскими плагинами Webpack.
Отключение кэша Webpack
Кэш Webpack сохраняет сгенерированные модули Webpack в памяти и/или на диске для ускорения сборок. Это может улучшить производительность, но также увеличит потребление памяти приложением для хранения кэшированных данных.
Вы можете отключить это поведение, добавив пользовательскую конфигурацию Webpack в ваше приложение:
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
if (config.cache && !dev) {
config.cache = Object.freeze({
type: 'memory',
})
}
// Важно: вернуть изменённую конфигурацию
return config
},
}
export default nextConfig
Отключение статического анализа
Проверка типов и линтинг могут потреблять много памяти, особенно в крупных проектах. Однако большинство проектов имеют выделенный CI-раннер, который уже выполняет эти задачи. Если сборка вызывает ошибки нехватки памяти на этапе "Linting and checking validity of types", вы можете отключить эти задачи во время сборки:
/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
// Предупреждение: Это позволяет успешно завершать продакшен-сборки,
// даже если в проекте есть ошибки ESLint.
ignoreDuringBuilds: true,
},
typescript: {
// !! ВНИМАНИЕ !!
// Опасная опция: позволяет успешно завершать продакшен-сборки,
// даже если в проекте есть ошибки типов.
// !! ВНИМАНИЕ !!
ignoreBuildErrors: true,
},
}
export default nextConfig
Учтите, что это может привести к деплою с ошибками типов или линтинга. Мы настоятельно рекомендуем продвигать в продакшен только те сборки, где статический анализ завершён успешно. При деплое на Vercel вы можете ознакомиться с руководством по стейджинг-деплоям, чтобы узнать, как продвигать сборки в продакшен после успешного выполнения пользовательских задач.
Отключение source maps
Генерация source maps потребляет дополнительную память во время сборки.
Вы можете отключить генерацию source maps, добавив productionBrowserSourceMaps: false
и experimental.serverSourceMaps: false
в конфигурацию Next.js.
Важно знать: Некоторые плагины могут включать source maps и могут требовать пользовательской конфигурации для отключения.
Проблемы с памятью в Edge runtime
В версии Next.js v14.1.3
была исправлена проблема с памятью при использовании Edge runtime. Обновитесь до этой версии (или новее), чтобы проверить, решает ли она вашу проблему.
Предзагрузка записей
При запуске сервера Next.js предзагружает JavaScript-модули каждой страницы в память, а не во время запроса.
Эта оптимизация обеспечивает более быстрые отклики в обмен на большее начальное потребление памяти.
Для отключения этой оптимизации установите флаг experimental.preloadEntriesOnStart
в false
.
import type { NextConfig } from 'next'
const config: NextConfig = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config
/** @type {import('next').NextConfig} */
const config = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config
Next.js не выгружает эти JavaScript-модули, поэтому даже с отключённой оптимизацией потребление памяти сервером Next.js в конечном итоге будет таким же, если все страницы будут запрошены.