TL;DR
Разбираем кейс ультраоптимизированного React-компонента шахматной доски с WASM-движком на Rust. Ключевые фичи: нулевые ререндеры при драге, подписка на отдельные клетки через useSyncExternalStore, Canvas для оверлеев и Web Animations API. Бандл <16 KB gzip.
Введение: почему это интересно
В эпоху SPA с их вечными проблемами перформанса, кейс шахматной доски от yahorbarkouski демонстрирует, как сочетание React, WASM и грамотной архитектуры позволяет достичь нативного уровня отзывчивости. Особенно показательно решение проблемы “драг без ререндеров” — больного места многих интерактивных интерфейсов.
Архитектурные решения
1. State management на уровне клеток
Вместо классического подхода с хранением состояния всей доски в React, здесь используется Uint8Array(64) (WASM shared memory), где каждый элемент соответствует клетке:
// Подписка клетки на свое состояние
const useSquare = (index: number) => {
return useSyncExternalStore(
(callback) => store.subscribe(index, callback),
() => store.getSnapshot(index)
);
};
Это дает точечные обновления — при ходе меняются только 2-4 клетки вместо всей доски.
2. Drag-n-drop без участия React
Драг реализован через отдельный слой на refs + Web Animations API:
const pointerLayer = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = pointerLayer.current;
if (!el) return;
el.addEventListener('pointermove', (e) => {
// Анимация через WAAPI, минуя React
pieceToDrag.animate(
{ transform: `translate(${e.clientX}px, ${e.clientY}px)` },
{ duration: 0, fill: 'forwards' }
);
});
}, []);
3. Canvas для оверлеев
Все стрелки и подсветки рисуются на Canvas, что исключает лишние DOM-элементы:
const drawArrow = (ctx: CanvasRenderingContext2D, from: Square, to: Square) => {
const [x1, y1] = getCoords(from);
const [x2, y2] = getCoords(to);
// ... векторная математика ...
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
// ... стилизация ...
};
Практические выводы
Когда стоит применять подобные оптимизации?
- Высокочастотные интеракции (драг, ресайз, скролл)
- Крупные grid-интерфейсы (таблицы, карты)
- Строгие требования к FPS (игры, анимации)
Альтернативы WASM
Для менее требовательных сценариев можно обойтись:
- Web Workers + Transferable Objects
- CSS transforms для анимаций
- Virtualized rendering для больших списков
Заключение
Разобранный кейс — отличный пример того, как современный веб уже сегодня может достигать нативной производительности. Ключевые технологии:
- React 18+ (selective hydration, useSyncExternalStore)
- WASM для критичного к перформансу кода
- Web Animations API вместо CSS-in-JS
- Canvas для сложных оверлеев
Для глубокого погружения рекомендую изучить:
Источник: https://www.reddit.com/r/reactjs/comments/1ssjy2i/built_an_ultrafast_react_chessboard_1_commitmove/