Subtree Suspense и типизация ошибок гидратации в React 19: как не потерять контроль над...
Subtree Suspense и типизация ошибок гидратации в React 19: как не потерять контроль над SSR React 19 меняет правила игры для SSR-приложений: Subtree Suspense разрывает блокирующую гидратацию, а строгая типизация ошибок упрощает дебаг production-крашей. Частая ошибка — думать, что Suspense по-прежнему ждёт всё дерево целиком. Subtree Suspense: гидратация без ожидания Раньше Suspense блокировал гидратацию всего дерева, пока не будет готов самый медленный дочерний компонент. В React 19 гидратируются только готовые ветки. Пример — боковая панель с формой и тяжелый график: <main> <InteractiveSidebar data={data.sidebar} /> <Suspense fallback={<Spinner />}> <HeavyGraph data={data.graph} /> </Suspense> </main> InteractiveSidebar гидратируется мгновенно после загрузки своих данных, не дожидаясь чанка с графиком. На медленных каналах это даёт прирост в воспринимаемой производительности до 30-40%. Ошибка: типизация ошибок гидратации В production ErrorBoundary часто ловит неизвестные ошибки. React 19 добавил тип HydrationError: type HydrationError = { type: 'HYDRATION_MISMATCH' | 'CHUNK_LOAD_FAILURE'; message: string; chunkName?: string; }; Кастомный ErrorBoundary фильтрует только эти ошибки: class StrictErrorBoundary extends React.Component<{ children: React.ReactNode; fallback: (error: HydrationError) => React.ReactNode; }> { state = { error: null as HydrationError | null }; static getDerivedStateFromError(error: unknown) { return isHydrationError(error) ? { error } : (() => { throw error; })(); } render() { return this.state.error ? this.props.fallback(this.state.error) : this.props.children; } } Типичная ошибка — игнорировать CHUNK_LOAD_FAILURE. Если не обработать, пользователь увидит сломанный интерфейс без части функционала. Дебаг гидратации: enableHydrationDebug В React 19 добавлен хелпер для dev-стенда: import { enableHydrationDebug } from 'react-dom'; enableHydrationDebug({ logLevel: 'verbose', includeDiff: true }); Он выводит diff, где серверный и клиентский DOM расходятся. Но есть нюанс: сторонние компоненты, мутирующие DOM после загрузки (например, аналитические скрипты), генерируют много шума. На production не включать — verbose-логи могут замедлить рендер. Практический совет Используйте Subtree Suspense только для критичных интерактивных элементов: формы, поиск, навигация. Для неинтерактивных блоков (статический контент) разницы нет, но код усложняется. Типизация ошибок гидратации через кастомный ErrorBoundary обязательна для мульти-чанков. Вывод: Subtree Suspense ускоряет гидратацию, но требует явного деления кода через lazy + Suspense и фильтрации ошибок гидратации через HydrationError, чтобы production оставался стабильным без побочных эффектов от шумных логов.