Как всё начиналось
В 2018 году нам нужно было создать сайт-портфолио для нашей студии веб-разработки. Мы решили отойти от шаблонных решений и создать что-то уникальное, черпая вдохновение из эстетики киберпанка 80-х и 90-х. Этот стиль отражён в наших любимых произведениях, таких как «Призрак в доспехах» (1995), «Матрица» (1999) и «Акира» (1988). Оттуда мы позаимствовали визуальные мотивы: катакану на главной странице и эффект декодирования текста как отсылку к «цифровому дождю» из «Матрицы».
Первая итерация
Когда мы начинали работу над сайтом, React только набирал популярность. Хотя для портфолио студии это было избыточно, мы видели в этом отличную возможность для экспериментов с новыми технологиями. Лучший способ освоить инструмент — это создать на нём реальный продукт.
Мы выбрали Create React App для быстрого старта проекта. В стек вошли Styled Components, Tween.js и React Transition Group. Также мы экспериментировали с Three.js — например, анимированная 3D-сфера на главной странице появилась именно тогда и живёт там до сих пор.
С тех пор сайт стал нашей лабораторией для тестирования новых технологий и подходов. Большим улучшением стала замена статических скриншотов проектов на интерактивные 3D-модели устройств, отрисовываемые в реальном времени.
Переход на современный стек
С Create React App мы использовали неуклюжее решение для предварительного рендеринга через Puppeteer. Это работало, н о мы хотели более надёжную платформу для публикации статей в формате MDX. После анализа вариантов (Gatsby, Vite, Parcel, Remix) мы выбрали Next.js как наиболее подходящий инструмент.
Что изменилось:
- Next.js вместо Create React App — гораздо более мощное решение для статического экспорта с возможностью добавить SSR в будущем
- Чистый CSS с postcss для поддержки современных функций (вложенность, пользовательские медиа-запросы)
- CSS-модули вместо BEM для изоляции стилей
- mdx-bundler для генерации страниц из
.mdxфайлов — быстро и элегантно - Framer Motion вместо Tween.js для продвинутых анимаций
- three-stdlib как современная альтернатива устаревшим примерам Three.js
Проблемы при миграции
В целом миграция прошла гладко благодаря схожести React Router и файловой маршрутизации Next.js. Но были нюансы:
1. Анимированные переходы между страницами
Next.js удаляет стили предыдущей страницы мгновенно при переходе. Это отлично для производительности, но ломает анимацию переходов — страница резко теряет всё оформление. Эта проблема — одна из самых обсуждаемых в репозитории Next.js. Пока мы используем временное решение из комментариев.
2. Управление прокруткой
Пришлось отключить как нативное, так и встроенное восстановление прокрутки Next.js, чтобы браузер не прокручивал страницу вверх во время анимации перехода. Также мы добавили управление фокусом при переходах к якорям для улучшения доступности.
Итоги и планы
Приятно видеть, что наш открытый исходный код на Github набрал 500+ звёзд. Многие адаптируют его под свои проекты и модифицируют — именно для этого мы сделали его open source. Мы хотим, чтобы другие разработчики могли изучать код, учиться и улучшать его.
Раньше можно было просто открыть инспектор в браузере и посмотреть, как сделан сайт. Сегодня с минификацией и обфускацией это почти невозможно. Открытый исходный код — наш вклад в сообщество.
Мы продолжаем использовать этот сайт как площадку для экспериментов с новыми технологиями.
Обновление: февраль 2024
Недавно мы перенесли сайт на Remix. Теперь у них отличная поддержка CSS-модулей, что позволило сохранить всю нашу стилизацию без изменений. В основном мы просто удалили все хаки, упомянутые выше, и всё заработало «из коробки».
Основные улучшения:
- CSS View Transitions API для плавных пере ходов между страницами — нативная браузерная функция, встроенная в React Router
- Cookie для темы — больше никаких javascript-хаков и вспышек нестилизованного контента
- Веб-стандарты — Remix следует платформенным стандартам, что делает код чище и надёжнее
В целом мы очень довольны Remix и рекомендуем его для современных веб-приложений. В планах — замена JavaScript-анимаций на будущий CSS API scroll-driven animations, когда поддержка браузеров станет достаточной.
