Создание эффектного портфолио: Next.js, TypeScript и анимации

Полное руководство по разработке современного портфолио с нуля, включающее глубокий разбор основ используемых технологий. Вы освоите связку Next.js и TypeScript, научитесь создавать стильные интерфейсы с Tailwind CSS и внедрять сложные анимации с Framer Motion и Lenis.

1. Фундамент стека: Глубокий разбор TypeScript, React и архитектуры Next.js

Фундамент стека: Глубокий разбор TypeScript, React и архитектуры Next.js

Добро пожаловать в первый модуль курса «Создание эффектного портфолио». Прежде чем мы начнем создавать сложные анимации с Framer Motion или настраивать плавную прокрутку с Lenis, нам необходимо построить прочный фундамент. Эффектное портфолио — это не только красивая картинка, но и производительность, масштабируемость и чистота кода.

В этой статье мы разберем «большую тройку» нашего стека: TypeScript, React и Next.js (с использованием App Router). Мы не будем читать документацию вслух, а сфокусируемся на архитектурных принципах, которые критически важны для современного веб-разработчика.

TypeScript: Ваша страховка от ошибок

Многие новички воспринимают TypeScript как «JavaScript, который заставляет писать больше кода». Однако в контексте профессиональной разработки, TypeScript — это инструмент документации и предотвращения ошибок на этапе написания кода, а не его выполнения.

Статическая типизация против Динамической

JavaScript — язык с динамической типизацией. Это значит, что переменная может хранить число, затем строку, а затем объект. Это удобно для быстрых скриптов, но губительно для крупных приложений.

TypeScript вводит строгую типизацию. Если вы определили, что функция принимает объект с данными о проекте, вы физически не сможете передать туда что-то другое.

Рассмотрим пример компонента карточки проекта для портфолио:

Интерфейсы и Типы

В нашем курсе мы будем часто использовать ключевое слово interface для описания форм объектов (например, пропсов компонентов) и type для создания союзов (Unions) или примитивов.

> TypeScript не запускается в браузере. Он компилируется (транспилируется) в обычный JavaScript. Браузер никогда не узнает о ваших интерфейсах, они нужны только вам и вашему редактору кода.

React: Мышление компонентами

React изменил способ создания интерфейсов, перейдя от манипуляции DOM-деревом к декларативному описанию состояния. Для нашего портфолио важно понимать три кита React: Компоненты, Пропсы и Состояние.

Декларативный подход

Вместо того чтобы говорить браузеру «найди элемент с ID 'button' и добавь ему класс 'active'», мы говорим: «Кнопка должна быть активной, если переменная isActive равна true». React сам решит, как обновить DOM.

Хуки: Управление жизненным циклом

В функциональных компонентах мы используем хуки. Для портфолио нам понадобятся в основном:

  • useState: Для хранения локального состояния (например, открыто ли модальное окно).
  • useEffect: Для выполнения побочных эффектов (например, запуск анимации при появлении элемента или подписка на событие скролла).
  • useRef: Для прямого доступа к DOM-элементу (критично для анимаций с GSAP или Lenis).
  • Пример использования useRef для анимации:

    Архитектура Next.js: App Router

    Next.js — это мета-фреймворк поверх React. Если React — это библиотека для создания UI, то Next.js — это полноценный каркас для создания веб-приложений. В версии 13+ был представлен App Router, который мы и будем использовать.

    Файловая маршрутизация

    В Next.js структура папок определяет URL вашего сайта. Это интуитивно понятно и удобно.

    !Структура файловой маршрутизации в Next.js App Router

    * app/page.tsx Главная страница (/) * app/about/page.tsx Страница «Обо мне» (/about) * app/projects/[id]/page.tsx Динамический маршрут (/projects/1, /projects/cool-app)

    Server Components (RSC) vs Client Components

    Это самая важная концепция в современном Next.js. По умолчанию все компоненты в папке app являются Серверными Компонентами (React Server Components).

    | Характеристика | Server Components (RSC) | Client Components | | :--- | :--- | :--- | | Где рендерятся | На сервере (один раз при запросе) | На клиенте (в браузере) и сервере (гидратация) | | Доступ к БД/Файлам | Прямой доступ | Нет доступа | | Размер JS-бандла | Не влияет (код не летит в браузер) | Увеличивает размер бандла | | Интерактивность | Нет (нельзя использовать onClick, useState) | Да (полная интерактивность) |

    Для портфолио это разделение критично. Тяжелые вычисления, получение данных о проектах из CMS или Markdown-файлов мы делаем в серверных компонентах. Анимации, слайдеры и формы обратной связи — в клиентских.

    Чтобы превратить компонент в клиентский, нужно добавить директиву 'use client' в первой строке файла.

    Специальные файлы

    В App Router есть зарезервированные имена файлов:

    * layout.tsx: Обертка для страниц. Здесь живут <html>, <body>, навигация и футер. Layout не перерисовывается при переходе между страницами внутри него, что идеально для сохранения состояния анимаций переходов. * page.tsx: Уникальный UI для конкретного маршрута. * loading.tsx: Показывается, пока грузится содержимое page.tsx. * not-found.tsx: Кастомная страница 404.

    Tailwind CSS: Утилитарный подход

    Вместо написания CSS-файлов и придумывания имен классов (.wrapper-main-content-left), мы используем утилитарные классы прямо в JSX.

    Пример:

    Это ускоряет разработку и гарантирует, что стили не будут конфликтовать. В сочетании с компонентами React, мы получаем изолированные, стилизованные блоки, которые легко переиспользовать.

    Подготовка окружения

    Для начала работы нам потребуется Node.js. Мы создадим проект следующей командой:

    При установке выберите следующие опции: * TypeScript: Yes * ESLint: Yes * Tailwind CSS: Yes * src/ directory: No (или Yes, по вкусу, но в курсе мы будем работать в корне) * App Router: Yes Customize default import alias: No (оставим @/)

    Заключение

    Мы разобрали фундамент. TypeScript обеспечит надежность данных, React даст нам компонентную модель, а Next.js App Router возьмет на себя маршрутизацию и оптимизацию производительности. Понимание разницы между Server и Client Components — ключ к созданию быстрого портфолио, которое нравится поисковикам и пользователям.

    В следующей статье мы начнем настраивать базовый макет и интегрировать Lenis для создания той самой «дорогой» плавной прокрутки.

    2. Визуальный стиль: Продвинутая верстка с Tailwind CSS и компонентный подход

    Визуальный стиль: Продвинутая верстка с Tailwind CSS и компонентный подход

    В предыдущем модуле мы заложили прочный фундамент, настроив Next.js, TypeScript и разобравшись с архитектурой приложения. Теперь пришло время вдохнуть жизнь в наш проект. Портфолио встречают по одежке, и именно визуальный стиль определяет первое впечатление работодателя или клиента.

    В этой статье мы отойдем от базового использования CSS и погрузимся в профессиональную работу с Tailwind CSS. Мы научимся создавать масштабируемые дизайн-системы, решать проблемы конфликтов стилей и использовать продвинутые техники верстки, которые сделают ваш сайт не только красивым, но и удобным для поддержки.

    Философия Utility-First: Почему не БЭМ?

    Если вы пришли из мира классического CSS или SCSS, подход Tailwind может показаться хаотичным. Вместо семантических классов вроде .portfolio-card__title, мы пишем .text-xl .font-bold .mb-2. Почему это стало стандартом индустрии?

  • Отсутствие контекстного переключения. Вам не нужно прыгать между файлом компонента (.tsx) и файлом стилей (.css). Структура и стиль живут в одном месте.
  • Меньший размер бандла. Tailwind генерирует только те классы, которые вы реально используете. В отличие от традиционного CSS, который только растет с добавлением новых фич, CSS-файл Tailwind стабилизируется.
  • Системность. Вы не придумываете «волшебные числа» (например, margin: 13px). Вы используете токены из дизайн-системы (m-4 = 1rem = 16px).
  • !Сравнение разделения ответственности в традиционном CSS и Utility-First подходе

    Настройка темы: Ваш уникальный бренд

    Портфолио должно быть уникальным. Использование стандартных цветов Tailwind сделает ваш сайт похожим на тысячи других. Вся магия кастомизации происходит в файле tailwind.config.ts.

    Мы расширим стандартную тему, добавив свои цвета и шрифты, вместо того чтобы перезаписывать их.

    Теперь в коде мы можем использовать bg-primary или text-accent. Если вы захотите провести ребрендинг, достаточно будет поменять hex-коды в одном файле.

    Проблема «Длинных строк» и Компонентный подход

    Главная претензия к Tailwind — длинные строки классов, загрязняющие JSX. Решение этой проблемы кроется в компонентном подходе React, о котором мы говорили в прошлой статье.

    Не копируйте одни и те же классы для каждой кнопки. Создайте компонент UI.

    Утилита cn (ClassNames)

    В профессиональной разработке на стеке React + Tailwind стандартом де-факто стало использование двух библиотек: clsx (для условного рендеринга классов) и tailwind-merge (для разрешения конфликтов).

    Представьте, что у вас есть компонент Button с отступами p-4. Вы хотите использовать его, но в одном месте вам нужен p-2. Если просто склеить строки, в CSS попадут оба класса, и результат будет зависеть от порядка их объявления в таблице стилей, а не от вашего кода.

    Создадим утилиту cn в файле lib/utils.ts:

    Теперь мы можем создавать гибкие компоненты:

    Использование:

    Здесь w-full и mt-4 корректно добавятся к кнопке.

    Продвинутые селекторы и состояния

    Для эффектного портфолио простых ховеров недостаточно. Нам нужны взаимодействия между элементами.

    Group и Group-Hover

    Частый паттерн: карточка проекта. Мы хотим, чтобы при наведении на всю карточку, увеличивалась картинка и менялся цвет заголовка.

    Для этого родительскому элементу даем класс group, а дочерним — group-hover:....

    Peer

    Модификатор peer позволяет стилизовать элемент в зависимости от состояния его соседа (предыдущего элемента). Это идеально для форм обратной связи.

    Адаптивная верстка: Mobile First

    Tailwind использует подход Mobile First. Это значит, что классы без префиксов работают на всех экранах (начиная с мобильных), а префиксы (md:, lg:) переопределяют их для больших экранов.

    > Ошибка новичка: писать sm:w-full md:w-1/2. > Правильно: w-full md:w-1/2. w-full уже работает для sm и ниже по умолчанию.

    Сетка проектов (Grid)

    Для галереи работ лучше всего использовать CSS Grid. Tailwind позволяет делать сложные сетки одной строкой.

    Если вы хотите, чтобы сетка заполнялась автоматически в зависимости от ширины карточки (без медиа-запросов), можно использовать произвольные значения (Arbitrary Values):

    Это создаст адаптивную сетку, где каждая колонка имеет минимум 300px ширины.

    Произвольные значения (Arbitrary Values)

    Иногда дизайн требует отступов или размеров, которых нет в стандартной шкале. Tailwind позволяет использовать квадратные скобки для "одноразовых" значений.

    * h-[500px] — фиксированная высота. * bg-[#123456] — специфичный цвет. * z-[100] — специфичный z-index.

    Однако, не злоупотребляйте этим. Если вы видите, что постоянно пишете text-[#38BDF8], лучше вынесите этот цвет в tailwind.config.ts.

    Темная тема (Dark Mode)

    Для разработчика наличие темной темы в портфолио — признак хорошего тона. В Tailwind это реализуется через класс dark.

    В tailwind.config.ts добавьте:

    Теперь вы можете использовать модификатор dark::

    Для переключения темы мы будем использовать библиотеку next-themes, которая сохраняет выбор пользователя в LocalStorage и предотвращает "мигание" темы при загрузке.

    Заключение

    Мы разобрали, как превратить хаос CSS-классов в стройную систему. Использование утилиты cn, правильная настройка конфига и понимание модификаторов group и peer позволят вам верстать сложные интерфейсы с невероятной скоростью.

    Ваше домашнее задание — создать компонент Card для будущего портфолио, используя cn для слияния классов и реализовать hover-эффект через group.

    В следующей статье мы заставим эти статичные блоки двигаться. Мы подключим Framer Motion и создадим анимации появления, которые вызовут "Wow-эффект" у посетителей.

    3. Искусство анимации: От основ до сложных техник работы с Framer Motion

    Искусство анимации: От основ до сложных техник работы с Framer Motion

    Добро пожаловать в третий модуль нашего курса «Создание эффектного портфолио». В предыдущих статьях мы построили надежный архитектурный фундамент на Next.js и TypeScript, а также создали стильную дизайн-систему с помощью Tailwind CSS. Но давайте будем честны: в 2024 году просто красивой статичной картинки недостаточно. Чтобы портфолио действительно «цепляло» и выглядело дорого, оно должно быть живым.

    Сегодня мы погрузимся в мир Framer Motion — самой мощной библиотеки анимаций для React. Мы пройдем путь от простого появления элементов до сложных скролл-эффектов и параллакса, которые заставят рекрутеров задержаться на вашем сайте.

    Почему Framer Motion?

    Вы можете спросить: «Зачем мне библиотека, если есть CSS Transitions?».

    CSS отлично подходит для простых состояний (например, изменение цвета кнопки при наведении). Но когда речь заходит о последовательной анимации списка проектов, переходов между страницами или реакции на скролл, CSS становится громоздким и трудно поддерживаемым.

    Framer Motion предлагает декларативный подход. Вместо того чтобы описывать как менять пиксели, вы описываете состояния, в которых должен находиться элемент. Библиотека сама рассчитывает физику движения.

    Фундамент: Компонент motion

    Сердце библиотеки — это компонент motion. Это обертка над стандартными HTML-элементами. Если вы хотите анимировать div, вы используете motion.div. Если h1motion.h1.

    У этого компонента есть три главных пропса:

  • initial: Состояние элемента до начала анимации (например, прозрачный и смещенный вниз).
  • animate: Конечное состояние, к которому элемент должен прийти.
  • transition: Настройки физики (длительность, задержка, тип анимации).
  • Рассмотрим пример появления заголовка:

    В этом примере заголовок появится из прозрачности и плавно поднимется на 20 пикселей вверх.

    Оркестрация с помощью Variants

    Когда у вас один элемент, пропсы initial и animate работают отлично. Но представьте, что у вас есть список из 10 карточек проектов, и вы хотите, чтобы они появлялись по очереди (каскадом). Копировать код в каждую карточку — плохая практика.

    Здесь на сцену выходят Variants (Варианты). Это способ вынести настройки анимации в отдельный объект и управлять ими через имена состояний.

    !Визуализация распространения анимации от родителя к детям через Variants

    Главная магия вариантов — пробрасывание анимации. Если вы зададите родительскому элементу состояние visible, все дочерние элементы тоже попытаются перейти в состояние visible, если у них есть такой вариант.

    Использование staggerChildren создает тот самый профессиональный эффект «лесенки», который так любят дизайнеры.

    Анимация при скролле: whileInView

    В портфолио важно не загружать пользователя анимациями сразу. Контент должен оживать по мере того, как пользователь скроллит страницу. Раньше для этого использовали Intersection Observer, но в Framer Motion это делается одним пропсом: whileInView.

    Настройка viewport={{ once: true }} гарантирует, что анимация проиграется только один раз. Без этого флага элемент будет исчезать и появляться каждый раз, когда вы прокручиваете его туда-сюда, что часто раздражает пользователей.

    Магия Parallax и useTransform

    Параллакс — это эффект, при котором фоновые элементы движутся медленнее (или в другом направлении), чем передний план. Это создает ощущение глубины.

    Для создания таких эффектов мы используем хуки useScroll и useTransform. Это требует понимания простой математической концепции: линейной интерполяции.

    Когда мы скроллим страницу, значение скролла меняется, например, от 0 до 1000 пикселей. Нам нужно преобразовать («спроецировать») это значение в другое, например, в угол поворота элемента.

    Формула линейной интерполяции выглядит так:

    Где: * — искомое значение (например, угол поворота). * — текущее входное значение (позиция скролла). * — диапазон входных значений (начало и конец скролла). * — диапазон выходных значений (начальный и конечный угол).

    К счастью, Framer Motion делает эти вычисления за нас.

    В этом примере фоновая картинка будет двигаться против направления скролла, создавая эффект глубины.

    Layout Animations: Магия перестроения

    Одна из самых сложных задач в веб-разработке — анимировать изменение структуры DOM. Например, когда вы фильтруете список проектов, и одни карточки исчезают, а другие плавно занимают их места.

    В Framer Motion для этого достаточно добавить проп layout.

    Когда массив filteredProjects изменится, Framer Motion автоматически вычислит новую позицию для каждого элемента и плавно переместит его туда. Без пропа layout элементы бы просто мгновенно перепрыгнули.

    Shared Layout Animations

    Вы наверняка видели эффект в App Store, когда при клике на маленькую карточку она разворачивается на весь экран. Это называется Shared Element Transition.

    Чтобы связать два разных компонента (маленькую карточку в списке и большую открытую карточку), нужно дать им одинаковый layoutId.

    Framer Motion поймет, что это «один и тот же» элемент, и плавно трансформирует маленький div в большой, искажая размеры и позицию.

    Оптимизация и Accessibility

    Анимации — это прекрасно, но они могут нагружать процессор и вызывать головокружение у некоторых пользователей.

    LazyMotion

    Чтобы уменьшить размер JS-бандла, используйте LazyMotion. Это позволяет загружать код анимаций только тогда, когда они действительно нужны.

    Reduced Motion

    Всегда уважайте настройки пользователя. Если человек отключил анимации в системе (режим «Reduced Motion»), ваше портфолио не должно мелькать.

    Заключение

    Мы разобрали основные инструменты Framer Motion, которые понадобятся вам для создания портфолио уровня Awwwards. Мы научились создавать каскадные появления с помощью variants, оживлять скролл через whileInView и useTransform, а также делать сложные перестроения макета одной строчкой кода layout.

    Ваше домашнее задание: возьмите сетку проектов из предыдущего урока и добавьте к ней анимацию появления staggerChildren, а также эффект параллакса для заголовка главной страницы.

    В следующей, завершающей статье технического блока, мы разберем Lenis — библиотеку для плавной инерционной прокрутки, которая свяжет все наши анимации воедино и придаст сайту то самое «премиальное» ощущение.

    4. Премиальный UX: Интеграция плавного скролла Lenis и параллакс-эффекты

    Премиальный UX: Интеграция плавного скролла Lenis и параллакс-эффекты

    Добро пожаловать в четвертый, завершающий технический модуль нашего курса «Создание эффектного портфолио». Мы уже проделали огромный путь: построили архитектуру на Next.js и TypeScript, создали дизайн-систему с Tailwind CSS и научились анимировать элементы с Framer Motion.

    Однако, если вы откроете наше портфолио сейчас и начнете прокручивать страницу, вы можете заметить, что чего-то не хватает. Скролл кажется «дерганым», резким, сугубо механическим. В мире премиального веб-дизайна (сайты Awwwards, портфолио топ-студий) прокрутка ощущается иначе — она имеет вес, инерцию и плавность.

    Сегодня мы добавим этот финальный штрих с помощью библиотеки Lenis, разберем математику плавности и создадим сложные параллакс-эффекты, которые работают в симбиозе с нативной прокруткой.

    Проблема стандартного скролла

    Браузерный скролл по умолчанию линеен. Когда вы крутите колесико мыши, браузер смещает страницу на фиксированное количество пикселей. Это эффективно, но скучно. Это не передает ощущение «физики» взаимодействия.

    Раньше разработчики использовали библиотеки вроде Locomotive Scroll, которые занимались так называемым Scroll Hijacking (перехватом скролла). Они полностью отключали нативный скролл браузера и эмулировали его с помощью transform: translateY(). Это создавало массу проблем:

  • Доступность (Accessibility): Ломалась навигация с клавиатуры и скринридеры.
  • Производительность: Тяжелые вычисления в основном потоке.
  • Нативные фичи: Переставали работать position: sticky и position: fixed.
  • Lenis изменил правила игры. Это библиотека нового поколения, которая не заменяет нативный скролл, а интерполирует его значения. Это значит, что все нативные функции браузера (поиск по странице, sticky-элементы, навигация) продолжают работать идеально.

    !Визуализация разницы между дискретным браузерным скроллом и интерполированным движением Lenis

    Математика плавности: Линейная интерполяция (Lerp)

    Прежде чем писать код, важно понять, как работает плавность. В основе лежит концепция Линейной интерполяции (Linear Interpolation, или Lerp).

    Представьте, что вы хотите переместить объект из точки А в точку Б. Вместо мгновенного перемещения, мы каждый кадр сдвигаем объект на определенный процент от оставшегося расстояния.

    Формула линейной интерполяции выглядит так:

    Где: * — новое значение позиции (куда мы сдвинемся в этом кадре). * — текущая позиция скролла. * — целевая позиция (куда пользователь крутанул колесико). * — коэффициент сглаживания (обычно от 0.01 до 0.1). Чем меньше число, тем плавнее (и медленнее) движение.

    Lenis выполняет эту формулу внутри цикла анимации браузера (requestAnimationFrame), обновляя позицию скролла 60-120 раз в секунду, создавая иллюзию инерции.

    Интеграция Lenis в Next.js App Router

    Поскольку Lenis работает с окном браузера (window), нам нужно инициализировать его в клиентском компоненте. В архитектуре Next.js 13+ мы не можем просто добавить код в layout.tsx, так как это серверный компонент.

    Создадим специальный компонент-обертку.

    Файл: src/components/providers/SmoothScroll.tsx

    Теперь обернем наше приложение в этот провайдер в корневом макете.

    Файл: src/app/layout.tsx

    Поздравляю! Теперь все ваше портфолио имеет приятную, «дорогую» инерцию при прокрутке.

    Симбиоз Lenis и Framer Motion

    В предыдущей статье мы использовали хук useScroll из Framer Motion. Хорошая новость: Lenis и Framer Motion отлично дружат, так как Lenis обновляет нативный скролл, который слушает Framer.

    Однако, для сложных эффектов иногда требуется синхронизация. Давайте создадим продвинутый компонент ParallaxImage, который использует плавность Lenis для создания эффекта глубины.

    Создание компонента ParallaxImage

    Идея: контейнер картинки имеет фиксированную высоту, а сама картинка внутри него выше контейнера и движется с другой скоростью при скролле.

    В этом примере мы используем h-[140%] (высота 140% от родителя) и сдвигаем картинку внутри маски. Благодаря Lenis, обновление значений scrollYProgress будет происходить плавно, без рывков.

    Эффект Sticky Scroll (Липкий скролл)

    Один из самых популярных паттернов в портфолио 2024 года — секции, которые «наслаиваются» друг на друга. Благодаря тому, что Lenis поддерживает нативный CSS, нам не нужен JavaScript для базовой логики.

    Достаточно использовать position: sticky.

    Lenis сделает момент «прилипания» карточек мягким, убирая микро-дрожание, которое иногда возникает в стандартном браузере.

    Оптимизация и подводные камни

    Интеграция плавного скролла требует ответственности. Вот несколько правил, которые спасут UX вашего портфолио:

    1. Не блокируйте скролл во время загрузки

    Некоторые разработчики скрывают overflow у body до полной загрузки сайта. Не делайте этого. Пользователь должен иметь контроль над интерфейсом сразу.

    2. Уважайте настройки движения

    Некоторых пользователей укачивает от параллакса и плавного скролла. Мы должны проверять медиа-запрос prefers-reduced-motion.

    В нашем компоненте SmoothScroll:

    3. Изоляция горизонтального скролла

    Если у вас есть горизонтальный слайдер внутри вертикальной страницы, Lenis может конфликтовать с ним. Чтобы этого избежать, добавьте атрибут data-lenis-prevent к контейнеру, который должен скроллиться нативно.

    Заключение технического блока

    Мы завершили техническую настройку нашего портфолио. Теперь у вас есть:

  • Next.js App Router для быстрой навигации и SEO.
  • TypeScript для надежности кода.
  • Tailwind CSS для стильной и быстрой верстки.
  • Framer Motion для анимации появлений и переходов.
  • Lenis для премиального ощущения от взаимодействия.
  • Этот стек — «золотой стандарт» для frontend-разработчика, желающего продемонстрировать высокий уровень навыков. Вы не просто сверстали макет, вы создали опыт (Experience).

    В следующих модулях мы отойдем от кода и поговорим о наполнении: как писать кейсы, какие проекты выбирать и как «продать» себя работодателю через контент. Но ваш технический фундамент теперь безупречен.

    5. Продакшн: Оптимизация производительности, SEO и деплой готового портфолио

    Продакшн: Оптимизация производительности, SEO и деплой готового портфолио

    Поздравляю! Вы прошли долгий путь. Мы начали с настройки TypeScript и Next.js, создали уникальную дизайн-систему на Tailwind CSS, оживили интерфейс с помощью Framer Motion и добавили премиальную плавность с Lenis. Ваше портфолио выглядит потрясающе на локальном сервере localhost:3000.

    Но «работает у меня на машине» — это не тот результат, который мы ищем. Профессиональное портфолио отличается не только визуальным стилем, но и тем, как быстро оно загружается, насколько хорошо индексируется поисковиками и как стабильно работает в реальном мире.

    В этой финальной статье мы превратим ваш проект в полноценный продукт. Мы займемся оптимизацией Core Web Vitals, настроим SEO-метаданные для социальных сетей и задеплоим сайт в глобальную сеть с помощью Vercel.

    Оптимизация производительности: Борьба за миллисекунды

    Красивые анимации не имеют значения, если сайт грузится 5 секунд. Пользователи (и рекрутеры) нетерпеливы. Next.js предоставляет мощные инструменты для оптимизации «из коробки», но их нужно уметь использовать.

    1. Оптимизация изображений с next/image

    Самая частая ошибка новичков — использование стандартного тега <img>. В современном вебе изображения должны быть адаптивными, сжатыми и в современных форматах (AVIF, WebP).

    Компонент Image из Next.js делает это автоматически:

  • Конвертация форматов: Автоматически отдает браузеру WebP или AVIF вместо тяжелых JPEG/PNG.
  • Предотвращение сдвига макета (CLS): Резервирует место под картинку до её загрузки.
  • Lazy Loading: Загружает изображения только тогда, когда они попадают в область видимости.
  • Пример использования:

    > Важно: Всегда добавляйте проп priority для изображений, которые видны на первом экране (LCP — Largest Contentful Paint). Это критически влияет на оценку Google Lighthouse.

    2. Шрифты и next/font

    Подключение шрифтов через Google Fonts в CSS часто приводит к проблеме FOIT (Flash of Invisible Text) или FOUT (Flash of Unstyled Text). Текст сначала не виден или отображается стандартным шрифтом, а потом «скачет», когда загружается нужный файл.

    !Иллюстрация проблемы сдвига макета (CLS) при загрузке веб-шрифтов

    Next.js решает это через модуль next/font. Он скачивает файлы шрифтов во время сборки (build time) и хостит их вместе с вашим сайтом. Никаких лишних запросов к Google.

    3. Разделение кода (Code Splitting) и next/dynamic

    Если в вашем портфолио есть тяжелые компоненты (например, 3D-сцена на Three.js или сложный график), не стоит загружать их в основной бандл. Используйте ленивую загрузку.

    SEO: Быть найденным

    Next.js App Router предоставляет элегантный API для управления метаданными. Вам больше не нужно вручную писать теги <meta> в head.

    Metadata API

    В любом page.tsx или layout.tsx вы можете экспортировать объект metadata.

    Open Graph: Красивые ссылки в соцсетях

    Когда вы скидываете ссылку на портфолио в Telegram или LinkedIn, должна подтягиваться красивая картинка-превью. Это настраивается через поле openGraph.

    Для динамической генерации картинок (например, для страницы конкретного проекта) можно использовать файл opengraph-image.tsx, который позволяет рисовать картинки с помощью CSS прямо на сервере, но для начала достаточно статической картинки в папке public.

    Деплой: Vercel

    Next.js создан компанией Vercel, поэтому их платформа — лучшее место для хостинга вашего портфолио. Это бесплатно для личных проектов, невероятно быстро и не требует сложной настройки серверов (DevOps).

    Процесс деплоя

  • GitHub: Убедитесь, что ваш код находится в репозитории на GitHub.
  • Регистрация: Зайдите на vercel.com и войдите через GitHub.
  • Импорт: Нажмите «Add New Project» и выберите репозиторий с портфолио.
  • Настройка:
  • * Framework Preset: Next.js (определится автоматически). * Environment Variables: Если вы использовали API ключи (например, для отправки формы через EmailJS), добавьте их здесь.
  • Deploy: Нажмите кнопку «Deploy».
  • Через минуту ваше портфолио будет доступно по адресу project-name.vercel.app.

    CI/CD Pipeline

    Самое приятное в Vercel — это автоматизация. Теперь, каждый раз, когда вы делаете git push в ветку main, Vercel автоматически:

  • Увидит изменения.
  • Запустит сборку (next build).
  • Если сборка прошла успешно, обновит сайт.
  • Если есть ошибки (например, TypeScript ругается на типы), деплой отменится, и вы получите уведомление.
  • Это и есть профессиональный процесс CI/CD (Continuous Integration / Continuous Delivery).

    Аналитика и Speed Insights

    После деплоя подключите вкладку Analytics и Speed Insights в панели Vercel. Это даст вам реальные данные о том, как пользователи взаимодействуют с сайтом:

    * Web Vitals: Реальная скорость загрузки у пользователей. * Visitors: Откуда приходят люди и какие проекты смотрят чаще всего.

    Заключение курса

    Мы прошли огромный путь. Вы создали не просто сайт-визитку, а сложный инженерный продукт.

    * TypeScript защищает вас от ошибок. * Tailwind CSS позволяет быстро менять дизайн. * Framer Motion и Lenis создают «вау-эффект». * Next.js обеспечивает мгновенную загрузку и SEO.

    Теперь ваша задача — наполнить это портфолио реальными кейсами. Помните: код — это важно, но контент — это король. Описывайте свои проекты так же тщательно, как вы писали код для этого портфолио.

    Удачи в поиске работы мечты!