#Симптомы и условия возникновения
Сервер Node.js начинает отвечать с большими задержками во время разбора крупного JSON: JSON.parse и JSON.stringify выполняются синхронно и занимают цикл событий. Это не обязательно нехватка сети или процессора в целом. Для начала проверьте используемую версию среды и точный текст ошибки на копии проекта, не меняя рабочий сервер.
#Причины и как их отличить
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Разбор большого тела запросаВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление. | Один запрос вызывает задержки у остальных клиентов | Ограничить допустимый размер тела и схему. |
| Крупная сериализация ответаВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление. | Зависание на JSON.stringify огромного объекта | Отдавать постранично или потоком. |
| Нет контроля сложности входаВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление. | Глубокие и объёмные структуры принимаются без ограничений | Проверять размер до разбора, замерять время. |
#Пошаговая диагностика и решение
- 1. Воспроизведите задержку на тестовом сервереОтправьте небольшой тестовый запрос, затем допустимый крупный файл без персональных данных. Измерьте время ответа обоих запросов; если второй задерживает первый, исследуйте синхронную обработку.
- 2. Измерьте время непосредственно вокруг разбораВ тестовом коде поставьте
performance.now()до и послеJSON.parseиJSON.stringify; не записывайте само тело JSON в лог. Длительное время на этой операции подтверждает причину задержек.
- 3. Проверьте ограничения размера запросовНайдите код или настройки фреймворка, где собирается тело запроса. В Express для используемого маршрута задайте обоснованный
express.json({limit: "1mb"})— только если 1 МБ соответствует контракту API; при превышении клиент должен получить контролируемую ошибку.
- 4. Переходите на постраничную выдачуПри выгрузке тысяч записей измените договорённость API: клиент запрашивает страницу и курсор. Не отправляйте всю базу одним JSON-объектом. Тестируйте согласованность выборки при добавлении данных.
- 5. Избегайте разбора всего файла целикомДля файлов в десятки/сотни мегабайт рассмотрите специализированный потоковый разбор JSON с проверяемой библиотекой и формат NDJSON при контроле обеих сторон. Обычный JSON.parse не является потоковым.
- 6. Используйте отдельный поток исполнения только при необходимостиWorker Threads подходят для CPU-нагрузки, но передача огромного объекта между потоками тоже стоит времени и памяти. Сначала измерьте затраты и используйте ограниченную очередь задач.
- 7. Сравните задержки после измененийПод одинаковым тестовым потоком сравните медианное и максимальное время лёгких запросов, ошибки по лимиту размера и расход памяти; при регрессии откатите изменение контракта API.
- Безопасный тест локального разбора JSONТекстБезопасный тест локального разбора JSON. Для настоящего профилирования измеряйте вход реального размера без записи личных данных.
import { performance } from 'node:perf_hooks'; const sample = JSON.stringify({ status: 'ok', items: [1, 2, 3] }); const start = performance.now(); const parsed = JSON.parse(sample); console.log('Разбор, мс:', (performance.now() - start).toFixed(3)); console.log(parsed.status);
#Как проверить результат и что делать, если не помогло
Во время допустимых тяжёлых операций простые запросы не зависают на прежние интервалы, слишком большой ввод отклоняется предсказуемо без падения сервера.
Если неисправность повторилась, выпишите первый код ошибки и действие, на котором она возвращается. Сравните версию Node.js/npm, рабочий каталог, настройки процесса и журнал тестового запуска. Откатите только внесённые изменения из предварительно сохранённой копии, затем разберите причину на отдельной среде.