Экосистема React за последнее десятилетие прошла путь от компактной библиотеки представлений до массивного архитектурного комбайна. Начиная с 18-й версии ядро подчинено конкурентному планированию (Concurrent Mode): задачи рендеринга делятся на кванты времени и распределяются по очередям с приоритетами. Однако в большинстве типичных веб-сервисов этот механизм не ускоряет работу, а лишь добавляет десятки килобайтов в бандл. Проект Redact от создателя TanStack Таннера Линсли предлагает альтернативный подход: синхронный рантайм, который на 100% совместим с API React 19, но сокращает размер клиентского кода на 66%.
Плата за конкурентность: как планировщик раздул бандл React
В оригинальной архитектуре React Fiber дерево компонентов превращено в сложный граф узлов с двунаправленными связями и 31 битовой маской приоритетов. Такая система проектировалась для огромных экранов с непрерывными фоновыми пересчетами. Но плата за универсальность оказалась заметной: стандартная сборка React 19.3.0 вместе с модулями DOM весит 69,1 КБ в сжатом виде (gzip).
Команда TanStack показала, что рядовые интерфейсы страдают не от нехватки квантования процессора, а от долгой загрузки скриптов по сети и запутанных асинхронных стек-трейсов. Redact возвращает классическую синхронную модель: компоненты вычисляются в одном непрерывном цикле без лишней прослойки планировщика. В итоге базовый размер рантайма в Vite падает до 23,3 КБ, а в минималистичном пресете nano — до 12,4 КБ.
Прозрачная подмена через плагин сборщика Vite
Главное практическое достоинство Redact — нулевой порог входа. Разработчикам не нужно переписывать компоненты или менять импорты. Плагин для Vite перехватывает обращения к библиотеке на этапе сборки и перенаправляет их на оптимизированные модули:
// vite.config.ts — подключение рантайма без изменения кодовой базы
import { defineConfig } from 'vite';
import { redact } from '@tanstack/redact/vite';
export default defineConfig({
plugins: [
// Плагин подменяет вызовы react и react-dom на легкий рантайм Redact
redact({
features: {
hydration: true, // поддержка серверной гидратации
viewTransitions: false, // интеграция с View Transitions API
},
}),
],
});
При этом в серверных окружениях с React Server Components (RSC) плагин сохраняет оригинальный React для корректной сериализации компонентов через @vitejs/plugin-rsc, изолируя замену исключительно на клиенте.
Синхронная модель: хуки React 19 без компромиссов
В кодовой базе сохраняются все ключевые механизмы современной экосистемы: хуки состояния, контексты, порталы, границы ошибок и новый оператор use для асинхронных данных внутри Suspense:
// src/components/UserProfile.tsx — стандартный компонент без упоминания Redact
import { useState, useTransition, Suspense, use } from 'react';
function UserDetails({ resource }: { resource: Promise<{ name: string; role: string }> }) {
const user = use(resource); // чтение промиса напрямую в теле компонента
return (
<div className="user-card">
<h4>{user.name}</h4>
<span className="badge">{user.role}</span>
</div>
);
}
export function UserProfile({ dataPromise }: { dataPromise: Promise<{ name: string; role: string }> }) {
const [count, setCount] = useState(0);
const [, startTransition] = useTransition();
const handleIncrement = () => {
// В Redact transition выполняется синхронно, сохраняя строгую предсказуемость
startTransition(() => {
setCount((prev) => prev + 1);
});
};
return (
<section className="profile-container">
<Suspense fallback={<p className="loading">Загрузка данных...</p>}>
<UserDetails resource={dataPromise} />
</Suspense>
<div className="counter-box">
<p>Счетчик: {count}</p>
<button onClick={handleIncrement} className="btn-secondary">
Увеличить
</button>
</div>
</section>
);
}
Благодаря отказу от квантования микротасок разреженные обновления состояния (sparse updates) на чипах Apple M5 Pro выполняются на 71,9% быстрее, чем в React 19 (0,002 мс против 0,009 мс), а стек-трейсы ошибок остаются прямыми и понятными.
Где Redact дает преимущество, а где лучше остаться на оригинале
Проект находится на стадии 0.1.0, но уже работает в продакшене на порталах tanstack.com и tannerlinsley.com. Библиотека проверена в связке с TanStack Router, TanStack Query и TanStack Table.
Отказ от конкурентного планировщика влечет осознанные ограничения: хук useDeferredValue возвращает текущее значение без искусственного откладывания, а useTransition исполняет код синхронно. Экспериментальные формы с useOptimistic пока возвращают базовые заглушки. Если приложению критически необходима фоновая приоритизация тысяч элементов, стандартный React незаменим. Но если требуется облегчить бандл на 45 КБ и убрать скрытые задержки в мобильных браузерах, Redact предлагает готовое решение без смены стека.
