Skip to content

Latest commit

 

History

History
124 lines (89 loc) · 10.3 KB

File metadata and controls

124 lines (89 loc) · 10.3 KB

Оптимизация производительности сайта

Рекомендации по ускорению загрузки и оптимизации кода для лучшего UX и метрик (LCP, FID, CLS). Применяются к публичной части в nextjs-project (App Router, layout и страницы в (site)).


Сделано

1. Главная страница — запросы к БД

  • Было: два одинаковых запроса постов (новости и статьи) с одними параметрами — лишний round-trip к БД.
  • Стало: два раздельных запроса с фильтром по type ('news' / 'article'). В блоках «Новости» и «Статьи» отображаются корректные данные, дублирования запросов нет.

2. Hero-изображение (LCP)

  • Было: next/image с unoptimized — отключена оптимизация (формат, размер, lazy).
  • Стало: unoptimized убран. Изображение обрабатывается через Image Optimization API (WebP/AVIF при поддержке), что улучшает LCP.

3. Лого в хедере

  • Было: обычный <img> без оптимизации.
  • Стало: next/image с priority и фиксированным контейнером. Лого в above-the-fold загружается с приоритетом.

4. Корзина — убран Framer Motion

  • Было: анимация открытия/закрытия через framer-motion (AnimatePresence, motion.div).
  • Стало: те же эффекты реализованы на CSS (transition opacity/transform). Панель и фон всегда в DOM, видимость через классы. Бандл без framer-motion на этой странице.

5. ISR вместо force-dynamic

  • Было: export const dynamic = 'force-dynamic' на главной, layout сайта, каталоге и странице категории — каждый запрос вёл к полному рендеру и запросам к БД.
  • Стало: export const revalidate = 60 (кэш на 60 секунд). Страницы отдаются из кэша и обновляются не чаще раза в минуту.

6. Шрифты Montserrat

  • Было: 6 начертаний (300, 400, 500, 600, 700, 800).
  • Стало: 3 начертания (400, 600, 700). Меньший объём загрузки шрифтов.

7. Пагинация каталога

  • Было: загрузка всех товаров на /catalog.
  • Стало: по 24 товара на страницу, навигация «Назад» / «Вперёд» и параметр ?page=. Запрос с take: 25 и skip для определения наличия следующей страницы.

8. Страницы товаров — ISR

  • Было: force-dynamic на product/[slug]/page.tsx и product/id/[id]/page.tsx.
  • Стало: revalidate = 60. Карточки товаров кэшируются на 60 секунд.

9. Корзина — доступность (a11y)

  • При закрытии панель и фон помечаются aria-hidden={true}, скринридеры их не озвучивают.
  • Для панели при закрытии выставляется атрибут inert (через ref + useEffect), чтобы элементы внутри не попадали в порядок табуляции.

10. Удалена зависимость framer-motion

  • В package.json удалён пакет framer-motion — в коде он больше не используется (корзина переведена на CSS).

Детальная проверка (аудит)

Проверка Статус
Главная: один тип запросов постов (news/article), без дублей ✅ Два запроса с разными type, дублей нет
Hero: нет unoptimized, есть priority
Лого в хедере: next/image + priority
Корзина: без framer-motion, анимации на CSS
revalidate 60 на главной, layout, каталоге, категории, товарах
Шрифты: только 400, 600, 700
Пагинация каталога: 24 на страницу, ?page=, Назад/Вперёд
Нет оставшихся force-dynamic в (site)
framer-motion удалён из package.json
Корзина: при закрытии не ловит фокус (inert + aria-hidden)

Пагинация: при ?page=abc или отрицательном значении используется страница 1. При ровно 24 товарах кнопка «Вперёд» не показывается.

Шрифты: в CSS используются font-weight: 500 и др. — браузер подставляет ближайшее начертание (400/600/700). При необходимости можно подключить 300 или 500 точечно.


Рекомендации по дальнейшей оптимизации

Рендеринг и кэш

Что Где Действие
revalidate Выставлен 60 с на главной, layout, каталоге, категории, страницах товара. При необходимости чаще обновлять контент — уменьшить значение; для более статичного — увеличить (например 300).

Изображения

Что Где Действие
Фоны категорий Главная, каталог — getCategoryBackgroundImage + style.backgroundImage Фоны задаются через CSS url(), Next Image не используется. Варианты: предзагрузка критичных фонов, использование next/image с fill в обёртке или сохранение текущего подхода с оптимизированными файлами (WebP, сжатие).
Картинки товаров ProductCard Уже используется next/image с sizes — ок. Следить, чтобы photo всегда был локальным путём или настроенным доменом в next.config.
Форматы Статика в /public Хранить hero, лого, фоны в современном формате (WebP/AVIF где возможно) и сжатыми — уменьшит вес и улучшит LCP.

Каталог и данные

Что Где Действие
Пагинация catalog/page.tsx Реализована: 24 товара на страницу, ссылки Назад/Вперёд. При очень большом каталоге можно добавить виртуализацию списка или бесконечный скролл.
Выборка полей Prisma-запросы Уже используется select/include только нужных полей — хорошо. Продолжать не тянуть лишние поля (например, content у постов на списках).

JavaScript и бандл

Что Где Действие
Framer Motion Убран из корзины, зависимость удалена из package.json.
Динамический импорт Тяжёлые компоненты Модалки, админские редакторы (TipTap и т.п.) подгружать через next/dynamic с ssr: false там, где они не нужны для первого рендера.
Шрифты layout.tsx — Montserrat Оставлены 3 начертания (400, 600, 700). При необходимости добавить 300/500/800 — подключать точечно.

Стили

Что Где Действие
globals.css ~1200 строк При росте файла можно выносить редко используемые блоки (например, анимации логина) в отдельные модули и подключать только на нужных маршрутах.
will-change / анимации Hero (aurora), marquee Уже используются. Следить за тем, чтобы will-change не висел на большом количестве элементов — только на анимированных.

Прочее

Что Действие
next.config В проекте используется next.config.ts. При использовании внешних изображений настроить images.domains / images.remotePatterns. Для локальных картинок дефолтная конфигурация достаточна.
Метрики Подключить замеры (e.g. Web Vitals в Vercel Analytics или через reportWebVitals) и отслеживать LCP, FID, CLS после изменений.

Чек-лист перед релизом

  • Проверить LCP: hero и лого без unoptimized, с priority где нужно.
  • Убедиться, что нет дублирующих запросов к БД на одной странице.
  • При большом каталоге — пагинация или ленивая подгрузка товаров.
  • Тяжёлые клиентские библиотеки — корзина на CSS; при неиспользовании framer-motion — удалить из зависимостей.
  • Шрифты: только нужные начертания (400, 600, 700) и subset (latin + cyrillic).