
Год на Vercel и один вечер переезда: bazariara.ge стал быстрее и снова открывается в России
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 раз.

Почему уехали с 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 мс |
| Москва → Vercel | 65 мс | 46–133 мс |
| Турция → Vercel | 10 мс | 9–11 мс |
Запросы к сайту с серверов
Три запроса подряд. Здесь мерили ответ-редирект с / на /ru, поэтому это время сервера, а не всей страницы.
| Откуда → куда | Подключение | Первый байт |
|---|---|---|
| Москва → Vercel | 48–199 мс | 0,24–0,88 с |
| Турция → Vercel | 43–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 и Турция. Но сеть — только часть ответа.
Сколько ждать первый байт страницы
| Маршрут | из Тбилиси | из Москвы и СПб |
|---|---|---|
| Vercel | 1,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. Переменные окружения — одной командой
npx vercel link
npx vercel env pull .env.vercel --environment=productionФайл целиком импортируется во вкладке «Переменные». Кавычки снимаются сами, служебные VERCEL_* и TURBO_* пропускаются.
*Импорт переменных из файла .env.vercel*
2. База — импорт по строке подключения
Во вкладке «База данных» есть импорт из другой базы: вставили строку подключения 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»
Что ускорили после переезда
Сразу после переезда оценка PR-CY даже упала — с 87 до 79. Сервер стал отвечать быстрее, но в браузере страница осталась тяжёлой: 5,5 МБ, из них 4,7 МБ — картинки. Дальше — работа над самой страницей.
| Что | До | После |
|---|---|---|
| 🖼 Картинки в каталоге | оригиналы 100–450 КБ: оптимизация выключена из-за квоты Vercel | WebP шириной 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 секунд и ни разу её не коснулся, в статистику не попадёт. Нас это устраивает.
Цифры
Оценки сервисов
| Проверка | Vercel | RelaxDev |
|---|---|---|
| PageSpeed Insights, мобильные | не замеряли | 100 |
| PR-CY, скорость загрузки | 87 | 100 |
| PR-CY, анализ сайта | не замеряли | 100 |
PageSpeed Insights, мобильные — после переезда
PR-CY, скорость загрузки — до оптимизации
PR-CY, скорость загрузки — после оптимизации
PR-CY, анализ сайта
PageSpeed Insights по категориям
Lighthouse 13.5, мобильный профиль: Moto G Power, медленный 4G.
| Категория | Сейчас |
|---|---|
| Производительность | 100 |
| Специальные возможности | 100 |
| Рекомендации | 100 |
| Поисковая оптимизация | 100 |
| Агентный просмотр | 3/3 |
| Метрика | Стили внутри HTML | Стили отдельным файлом |
|---|---|---|
| First Contentful Paint | 1,1 с | 1,0 с |
| Largest Contentful Paint | 1,4 с | 1,3 с |
| Total Blocking Time | 20 мс | 30 мс |
| Cumulative Layout Shift | 0 | 0 |
| Speed Index | 1,3 с | 2,4 с |
Почему две колонки — ниже, в разделе «Стили: внутри HTML или файлом».
«Агентный просмотр» — новая категория Lighthouse: насколько сайт удобен AI-агентам. Она проверяет дерево доступности, стабильность вёрстки, файл llms.txt и разметку WebMCP.
Метрики загрузки страницы /ru в PR-CY до оптимизации
| Метрика | Vercel | RelaxDev, сразу после переезда |
|---|---|---|
| Оценка | 87 | 79 |
| First Contentful Paint | 1,1 с | 1,8 с |
| Speed Index | 4,9 с | 2,7 с |
| Time to Interactive | 8,4 с | 8,5 с |
| Total Blocking Time | 150 мс | 240 мс |
| Cumulative Layout Shift | 0 | 0,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 внутри HTML | 260 КБ | 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 + Neon | 1,56–3,54 с | 3,5–3,6 с | 0,46–0,67 с | 0,60–0,94 с |
| RelaxDev, база ещё в Neon | 8,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.xml | 30 | 928 |
| Адреса главной и категорий в sitemap | со слэшем, каждый — редирект | совпадают с canonical |
lang на английских и грузинских страницах | ru | en, ka |
| Страницы подкатегорий туризма | 0 | 8: палатки, мангалы, дрова, термосы… |
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 и уверены, что на праздники сайт будет доступен.
Ссылки на замеры:
- PageSpeed Insights: pagespeed.web.dev/analysis/https-bazariara-ge-ru/xe3ssq4poa?form_factor=mobile
- PR-CY, скорость: pr-cy.ru/speed_test/?device=mobile&url=https%3A%2F%2Fbazariara.ge%2Fru
- PR-CY, анализ сайта: a.pr-cy.ru/bazariara.ge/
Комментарии (0)
Ответить без регистрации