Год на Vercel и один вечер переезда: bazariara.ge стал быстрее и снова открывается в России
Назад в блог

Год на Vercel и один вечер переезда: bazariara.ge стал быстрее и снова открывается в России

R
relaxdev
03.10.2026 24 просмотров 0

Bazari Ara — интернет-магазин грузинских продуктов, подарков и туристического снаряжения в Тбилиси. Next.js 16, PostgreSQL, картинки в объектном хранилище. Проекту около года, и весь этот год он жил на Vercel с базой в Neon.

Мы перенесли его на RelaxDev и сами не ожидали такого результата:

  • ✅ 100 из 100 на трёх проверках: PageSpeed Insights, скорость и анализ сайта в PR-CY;
  • ⚡ из Тбилиси сервер отвечает за 0,12–0,14 с вместо 1,5–3,5 с;
  • 🇷🇺 сайт снова открывается из России, из Москвы ответ — 0,02–0,03 с;
  • 🪶 страница легче в 7 раз, HTML главной — втрое, картинка в каталоге — в 10 раз.

Итог: 100 из 100


Почему уехали с Vercel

ПроблемаЧто это значило для магазина
🚫 Сайт недоступен в РоссииУ обычных провайдеров и мобильных операторов магазин не открывался. Главная причина переезда
🗄 Лимиты базыБесплатный тариф Neon упирался в лимиты, а платить за базу отдельно от хостинга не хотелось
🧊 Агрессивный кэшVercel долго отдавал старые карточки товаров: цену или наличие поменяли, а посетители видят прежнее
🖼 Квота на оптимизацию картинокОптимизацию изображений пришлось выключить, чтобы не выгорала квота. Каталог отдавал оригиналы по 100–450 КБ
🐢 Холодный стартПервый посетитель после паузы ждал ответа сервера 1,5–3,5 секунды

Куда переезжать: Россия, Турция или Польша

Почти все покупатели — из Грузии, часть — из России. Прежде чем переезжать, замерили все варианты: пинги между серверами, запросы с серверов и Globalping — по три точки в Тбилиси (Magticom, TradeZone, Cloud 9) и три в Москве и Санкт-Петербурге (Yandex.Cloud, Timeweb, Selectel).

Кандидаты:

  • Vercel — где сайт жил;
  • Россия — RelaxDev, наш сервер в Москве;
  • Турция — тестовый сервер, куда можно вынести приложение или поставить прокси;
  • Польша — сервер, через который у RelaxDev уже работает зарубежный вход для доменов.

Пинги между серверами

Откуда → кудаПинг, среднееРазброс
Москва → Турция83 мс78–87 мс
Турция → Москва79 мс78–80 мс
Москва → Vercel65 мс46–133 мс
Турция → Vercel10 мс9–11 мс

Запросы к сайту с серверов

Три запроса подряд. Здесь мерили ответ-редирект с / на /ru, поэтому это время сервера, а не всей страницы.

Откуда → кудаПодключениеПервый байт
Москва → Vercel48–199 мс0,24–0,88 с
Турция → Vercel43–69 мс0,20–0,40 с
Турция → RelaxDev через прокси в России0,25–5,16 с0,84–5,36 с

Последняя строка — главное открытие. Канал «Турция → Россия» нестабилен на новых соединениях: подключение иногда занимает пять секунд.

Насколько близко каждая площадка к покупателям

Globalping, время подключения (TCP) — чистая сеть, без работы сервера.

Площадкаиз Тбилисииз Москвы и СПб
Vercel (точка присутствия прямо в Тбилиси)2–39 мс6–87 мс
Турция30–99 мс77–95 мс
Польша71–82 мс42–72 мс
Россия, RelaxDev напрямую85–121 мс0–12 мс

По сети ближе всех к Грузии Vercel и Турция. Но сеть — только часть ответа.

Сколько ждать первый байт страницы

Маршрутиз Тбилисииз Москвы и СПб
Vercel1,56–3,54 с0,46–0,67 с
Турция как прокси в Россию0,29–0,56 с0,66–1,14 с
Польша как вход в Россию ¹0,15–0,16 с0,12–0,14 с
Россия, RelaxDev напрямую0,12–0,14 с0,02–0,03 с

Для сравнения: статическая страница, отданная nginx прямо с турецкого сервера, — 0,04–0,09 с из Тбилиси. Сервер в Турции хорош, но только если на нём живёт всё сразу.

¹ Замер на другом проекте платформы, который уже работает через польский вход. Там же замерен прямой путь в Россию: 0,10–0,13 с из Тбилиси — те же цифры, что у bazariara.

База должна стоять рядом с приложением

Это проверили на себе. Пока приложение уже работало в России, а база оставалась в Neon (Франкфурт):

ЗамерРезультат
Подключение к Neon из России0,8 с только на установку соединения
Страница из Тбилиси, холодный кэш8,5–9,6 с
Та же страница из Москвы, кэш уже прогрет0,13 с
pg_dump из Neon напрямую в Россиюзавис, прервали вручную
pg_dump через сервер в Польше12,6 с

Каждый запрос страницы к базе за границей платил за дорогу туда и обратно, поэтому сначала переносим базу и только потом меряем скорость.

Почему не Турция

  • С мобильного интернета в России сайт на турецком сервере не открывался. Российские мобильные операторы плохо держат соединения с зарубежными хостингами. Пришлось бы разводить посетителей по странам через GeoDNS.
  • Прокси через Турцию только добавляет путь: из Тбилиси первый байт 0,29–0,56 с против 0,12–0,14 напрямую, из Москвы — до секунды.
  • Канал «Турция → Россия» нестабилен: подключение от 0,25 до 5,2 секунды.
  • Если держать в Турции само приложение, туда же переезжает и база. Получается вторая площадка и вторая база.
  • Выигрыш по сети для Грузии — 30–60 мс. Это не стоит второй площадки, второй базы и GeoDNS.

Почему не Польша

Польский вход нужен тем, у кого прямой путь в Россию режется (например, с иностранных VPN). С мобильного интернета в России сайт через него открывается, но с задержкой, и неизвестно, надолго ли. Для Грузии он медленнее прямого: TLS-рукопожатие идёт через лишнее плечо, 219–241 мс против 106–136 напрямую.

Вывод: проще и быстрее всего — напрямую в Россию, на RelaxDev. Грузия получает первый байт за 0,12–0,14 с, Россия — за 0,02–0,03 с, площадка и база одни.


Как переезжали

1. Переменные окружения — одной командой

Bash
1
2
npx vercel link
npx vercel env pull .env.vercel --environment=production

Файл целиком импортируется во вкладке «Переменные». Кавычки снимаются сами, служебные VERCEL_* и TURBO_* пропускаются.

Импорт переменных из Vercel во вкладке «Переменные» *Импорт переменных из файла .env.vercel*

2. База — импорт по строке подключения

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

Импорт базы из Neon по строке подключения Импорт базы из Neon по строке подключения

3. Код — правки под постоянный сервер

На Vercel каждая функция живёт отдельно, на RelaxDev приложение работает одним долгоживущим процессом.

Было (под Vercel)СталоЗачем
ssl: 'require' всегдаSSL по строке подключенияNeon требует SSL, база платформы работает внутри сети без него
max: 1 — одно соединениепул по умолчанию (до 10)Запросы страницы через Promise.all идут одновременно, а не по очереди
prepare: falseпо умолчаниюНужно было только для пулера Neon

4. DNS — через Cloudflare

У регистратора .ge в зоне осталась скрытая запись Vercel (216.198.79.1, TTL 3600), которой не было видно в панели: DNS отдавал оба адреса, и часть посетителей попадала на старый сайт. Решили сменой A-записей на Cloudflare. Записи — в режиме «DNS only»: Cloudflare только отвечает, какой адрес у домена, а трафик идёт напрямую на сервер.

A-записи в Cloudflare в режиме DNS only A-записи в Cloudflare, режим «DNS only»


Что ускорили после переезда

Сразу после переезда оценка PR-CY даже упала — с 87 до 79. Сервер стал отвечать быстрее, но в браузере страница осталась тяжёлой: 5,5 МБ, из них 4,7 МБ — картинки. Дальше — работа над самой страницей.

ЧтоДоПосле
🖼 Картинки в каталогеоригиналы 100–450 КБ: оптимизация выключена из-за квоты VercelWebP шириной 256–640 px через оптимизатор Next.js — на своём сервере он бесплатный
🎞 Слайдер в карточкебраузер сразу грузил все фото: 20 карточек — около 33 картиноквторое и следующие фото — только когда человек потянулся к галерее
📦 Данные карточки товара в HTML~6 КБ на товар: три полных описания и служебные поля~1,2 КБ: только то, что карточка показывает
🏠 Главнаявесь каталог: 20 карточек, 4 фото сразу, одно из них — 436 КБпервый экран — текст и поиск, разделы с ленивыми фото ниже
✂️ JS главнойгрузила код каталога — слайдер, карточки, фильтры (~100 КБ)каталог — отдельный маршрут, адреса категорий прежние
🎨 CSSдва файла блокировали первую отрисовку (460 мс)один файл 8,6 КБ: 170 мс только при первом заходе, дальше из кэша на всех страницах
💬 Чат поддержкив обязательном JS каждой страницыгрузится после отрисовки
📊 Счётчики (Google, Метрика, Facebook, ~280–390 КБ JS)грузились вместе со страницейпо первому действию посетителя или через 5 секунд; роботам не грузятся вовсе
♻️ Кэш страництерялся при холодном старте функцийживёт в процессе до следующего деплоя, обновляется в фоне

Про счётчики честно: человек, который закрыл страницу быстрее чем за 5 секунд и ни разу её не коснулся, в статистику не попадёт. Нас это устраивает.


Цифры

Оценки сервисов

ПроверкаVercelRelaxDev
PageSpeed Insights, мобильныене замеряли100
PR-CY, скорость загрузки87100
PR-CY, анализ сайтане замеряли100

Итог: 100 из 100 PageSpeed Insights, мобильные — после переезда

PR-CY, скорость — до оптимизации PR-CY, скорость загрузки — до оптимизации

PR-CY, скорость — 100 PR-CY, скорость загрузки — после оптимизации

PR-CY, анализ сайта — 100 PR-CY, анализ сайта

PageSpeed Insights по категориям

Lighthouse 13.5, мобильный профиль: Moto G Power, медленный 4G.

КатегорияСейчас
Производительность100
Специальные возможности100
Рекомендации100
Поисковая оптимизация100
Агентный просмотр3/3
МетрикаСтили внутри HTMLСтили отдельным файлом
First Contentful Paint1,1 с1,0 с
Largest Contentful Paint1,4 с1,3 с
Total Blocking Time20 мс30 мс
Cumulative Layout Shift00
Speed Index1,3 с2,4 с

Почему две колонки — ниже, в разделе «Стили: внутри HTML или файлом».

«Агентный просмотр» — новая категория Lighthouse: насколько сайт удобен AI-агентам. Она проверяет дерево доступности, стабильность вёрстки, файл llms.txt и разметку WebMCP.

Метрики загрузки страницы /ru в PR-CY до оптимизации

МетрикаVercelRelaxDev, сразу после переезда
Оценка8779
First Contentful Paint1,1 с1,8 с
Speed Index4,9 с2,7 с
Time to Interactive8,4 с8,5 с
Total Blocking Time150 мс240 мс
Cumulative Layout Shift00,01
Largest Contentful Paint—4,4 с
Ответ сервера (TTFB)—110 мс

После оптимизации PR-CY ставит 100 — скриншот выше. Правая колонка честно показывает: переезд сам по себе скорость в браузере не дал. Главное ускорение — от картинок, облегчённой главной и отложенных счётчиков. Но на Vercel это упиралось в квоту на картинки и устройство платформы.

Вес страницы

После переезда, до оптимизацииСейчас
Вся страница со всеми файлами ²5 478 КБ, 84 запроса723 КБ, 58 запросов
Картинки на странице ²4 735 КБ, 43 шт.179 КБ, 20 шт.
HTML главной354 КБ110 КБ
Данные React внутри HTML260 КБ57 КБ
Стили2 файла, блокировали отрисовку на 460 мс1 файл, 8,6 КБ, дальше из кэша
Картинка товара, пример436 КБ (оригинал)44 КБ ³

² PR-CY, замер до того, как отложили счётчики: сейчас из этих 723 КБ ещё около 280 КБ скриптов Google и Метрики при первой загрузке не скачиваются.

³ Размер JPEG при запросе без поддержки webp. Браузеры получают webp — ещё легче.

Стили: внутри HTML или файлом

Next умеет встраивать CSS прямо в страницу (experimental.inlineCss). Мы сначала так и сделали: исчез отдельный запрос за стилями перед первой отрисовкой, и Lighthouse поставил 100. Потом разобрали HTML и увидели, что Next вписывает стили трижды: 40 КБ в тег <style> и ещё дважды по 40 КБ в данные React. Из 232 КБ HTML главной 121 КБ были стилями — в каждой открытой странице.

Вернули стили отдельным файлом. HTML главной стал 110 КБ вместо 232, данные React — 57 КБ вместо 139. Файл стилей весит 8,6 КБ, скачивается один раз за визит и дальше берётся из кэша на всех страницах. Это выгодно посетителям, которые смотрят несколько страниц, и поисковым роботам, которые обходят все 928 адресов.

Цена: при самом первом заходе браузер ждёт файл стилей — 170 мс на медленном 4G. Из-за этого в лабораторном замере Speed Index вырос с 1,3 до 2,4 с. Первая отрисовка и LCP не ухудшились, а 2,4 с — всё ещё «зелёная» зона.

Ответ сервера по этапам переезда

Globalping, страница /ru, по три точки в каждой стране.

ЭтапТбилиси: первый байтТбилиси: весь ответ ⁴Москва и СПб: первый байтМосква и СПб: весь ответ ⁴
Vercel + Neon1,56–3,54 с3,5–3,6 с0,46–0,67 с0,60–0,94 с
RelaxDev, база ещё в Neon8,5–9,6 с9,0–10,8 с0,12–0,13 с0,19–0,23 с
RelaxDev + своя база0,16–0,17 с0,36–0,39 с0,05 с0,11–0,13 с
RelaxDev после оптимизации0,12–0,14 с0,42 с0,02–0,03 с0,12–0,20 с

⁴ В «весь ответ» входит поиск адреса по DNS. В последнем замере домен уже был на Cloudflare и резолвился заново (40–150 мс), в предыдущем адрес был в кэше (1–30 мс).

У Vercel в цифрах есть холодный старт функции. Но именно его и видит реальный посетитель, который зашёл после паузы. Точки замера в московских дата-центрах до Vercel доходили, а у обычных провайдеров и мобильных операторов сайт не открывался.


SEO и AI-агенты

Раз уж взялись за скорость, прошлись и по технической стороне.

БылоСтало
Адресов в sitemap.xml30928
Адреса главной и категорий в sitemapсо слэшем, каждый — редиректсовпадают с canonical
lang на английских и грузинских страницахruen, ka
Страницы подкатегорий туризма08: палатки, мангалы, дрова, термосы…
llms.txt для AI-ассистентовпрошлогодний ассортимент, ссылки на удалённые разделысобирается из базы
Название у иконки корзинынет — для скринридеров и агентов «ссылка без имени»есть
Форма поискаобычнаяразмечена WebMCP: браузерные агенты видят её как инструмент «поиск товаров»

Подкатегории — отдельная история. По запросам «палатки», «дрова», «мангалы» магазин уже стоял на 3–4 месте, но страниц под эти запросы не было: у товаров не была проставлена подкатегория. Проставили по названиям товаров, и появилось восемь новых страниц со ссылками с главной.


Что всплыло после переезда

Переезд занял вечер. Следующие дни ушли на то, что всплыло потом, — возможно, эта часть полезнее цифр.

Sitemap на 30 адресов. Next собирал sitemap один раз, во время сборки, а базы при сборке не было. Ошибки базы ловились молча, и в sitemap оставались только статичные страницы — до следующей сборки. Теперь он строится на каждый запрос.

**Заглушки вместо переменных окружения.** Платформа при сборке подставляет вместо незаданных переменных заглушки вида auto-generated-stub-for-build, и они доживают до работы сервера. Всё, что начинается с NEXT_PUBLIC_, Next вшивает в код при сборке, поэтому пиксель Meta получил ID-заглушку. Теперь заглушки вычищаются при старте сервера, а их список пишется в лог: сразу видно, какие переменные забыли перенести с Vercel.

**Telegram из России.** С сервера в России api.telegram.org напрямую не открывается, а через него идут уведомления о заказах и чат поддержки. Запросы пошли через HTTP-прокси: для HTTPS это туннель, прокси видит только адрес, а не токен и не текст. Входящие сообщения от Telegram идут через приёмник платформы на зарубежном сервере. Сверьте, с каким секретом он ставит вебхук: у нас сначала были 401.

Маска телефона, которая теряла клиентов. Не про скорость, но всплыло в те же дни. Поле телефона обрезало вставку по длине и не убирало код страны: «+7 989 156-35-49» превращалось в «+7 798915635», и заказ не уходил. Теперь номер можно вставить как угодно — с +7, с 8, со скобками, — а страна определяется по коду сама.

**Старая строка prisma db push --accept-data-loss в билдере relaxdev.ru.** Prisma в коде давно не использовалась, а строка осталась. Пока у сборки не было доступа к базе, она молча падала. Дай мы ей доступ — привела бы базу в соответствие со схемой, где нет таблиц блога и чата поддержки.


Итог

  • ✅ Сайт снова открывается из России.
  • ✅ 100 из 100 в PageSpeed Insights, в скорости и в анализе сайта PR-CY.
  • ✅ В Грузии сервер отвечает за 0,12–0,14 с вместо 1,5–3,5, вся страница приходит за 0,42 с вместо 3,5.
  • ✅ Страница легче в 7 раз: 723 КБ вместо 5,5 МБ, HTML главной — 110 КБ вместо 354, картинки в каталоге — в 10 раз легче.
  • ✅ Нет лимитов базы и устаревших карточек.
  • ✅ В sitemap 928 адресов вместо 30.
  • ✅ Весь переезд — один вечер: переменные одной командой, база по строке подключения, пара правок в коде.
  • ✅ Не считаем лимиты ресурсов на Vercel и уверены, что на праздники сайт будет доступен.

Ссылки на замеры:

Проект из статьи
bazariara

Комментарии (0)

Ответить без регистрации

Изображения, PDF, TXT • Ctrl+V для скриншота • до 5 файлов, 10 MB
Пока нет комментариев. Будьте первым!