Node-процесс, который держал все локали
Vue SSR рендерил русский и всё равно выделял файлы en и de. Изолят рос с каждой страницей.
Контейнер vue после тихого утра сидел на 700 МБ. Утечки в коде приложения не было. SSR-entry на каждый рендер импортировал полный i18n JSON для en, ru и de, потом выбирал одну локаль. Node держал две другие в изоляте. Долгоживущий процесс это не отдавал.
HTML-payload повторял ту же ошибку. В сериализованном состоянии ехали все три словаря, чтобы клиент менял язык без навигации. Язык без навигации никто не менял. Лишний JSON лежал в документе и в куче.
Проблема была в изоляте, который держал все локали сайта с локалью уже в URL. Посетители платили TTFB и толстым первым документом. Нужна была одна таблица сообщений на запрос и перезапуск, когда куча росла.
Что entry грузит сейчас
SSR-сервер грузит сообщения локали запроса, а не всего сайта. Клиент гидрирует только эту таблицу. Смена языка бьёт в новый URL и новый документ. Так роутер уже работает.
Импорт JSON локали динамический. Процесс Node не require два других файла на русском рендере. Статический текст, который не слушает i18n, остаётся в серверном рендере и не едет в payload гидратации.
- Статические области, которые не слушают i18n, остаются только серверными.
- Форматированные даты попадают в сериализованное состояние. Клиент не считает их на mount.
- Процесс vue перезапускается по потолку памяти, та же идея, что pm.max_requests у PHP-FPM.
Куча на прогретом воркере села около 180 МБ. Из первого HTML ушли словари, которые не нужны. Hydration warning из-за расхождения дат по локали ушли вместе с ними.
Какой опыт из этого
SSR, который импортирует все локали, это запланированная утечка. Изолят не забывает ненужный JSON.
Смена языка на клиенте без навигации это продукт, которого не было. Три словаря ради него были бесплатны в дизайне и дороги в документе.
Процесс Node надо перезапускать. Долгоживущий SSR это PHP-FPM без max_requests, пока не поставлю потолок.
