Магазин работал и приносил заказы, но вырос быстрее, чем его код. Каталог на 17 тысяч шин обновлялся ночной выгрузкой поставщика, и эта выгрузка не укладывалась в отведённое время, а при сбое у поставщика могла обнулить каталог целиком. Журнал ошибок дорос до 6,4 ГБ, база — до 7,3 ГБ, из которых 7,1 ГБ занимали просроченные сессии. У карточек товаров не было ни человеческих адресов, ни canonical, и 42 % каталога пересоздавалось за месяц — проиндексированные страницы постоянно умирали. Карты сайта не было вовсе. Главная отвечала от одной до шести секунд. Отдельная беда — подбор: покупатель, который знает только марку своей машины, найти шины не мог, а поиск отделения Новой Почты не работал вообще.
Колесо Трейдинг: полное обновление интернет-магазина шин
Магазин шин на 17 тысяч позиций: новый интерфейс, три способа подбора, ускорение в пять раз и переделанная структура каталога — без остановки продаж.
- Ниша
- Шины
- Тип проекта
- Полное обновление интернет-магазина шин
- Платформа
- OpenCart 3
- Адрес
- koleso-trading.com



Сначала подняли полную копию магазина с отдельной базой — всё делалось на ней, боевой сайт не останавливался ни на день. Тему решили не переписывать: в ней 13 собственных модулей, и 31 из 39 установленных патчей завязан на её шаблоны. Вместо этого завели свой слой стилей, который подключается последним, и переписали интерфейс поверх рабочего движка — карточку товара, шапку с мегаменю, фильтр, оформление заказа, тёмную тему и всю адаптацию под телефон. Параллельно переделали то, что не видно: структуру каталога, постоянные адреса товаров, ночной обмен, кеширование и индексы. Переключение на новую версию заняло 11 минут простоя.
Главная отвечает за 0,2 секунды вместо шести, ночное обновление каталога проходит за 74 секунды одним проходом, адрес карточки больше не меняется никогда, а карта сайта на 35 тысяч адресов пересобирается каждую ночь. Покупатель подбирает шины тремя способами — по типоразмеру, по автомобилю и разноширокими комплектами, — видит цены всех складов в одной карточке и получает рабочую доставку Новой Почтой. Заявки дублируются в Telegram, формы закрыты от ботов.
Состав работ по проекту
Интерфейс переписан поверх темы
Карточка товара, шапка с мегаменю, фильтр, корзина, оформление заказа и тёмная тема — своим слоем стилей, который переживает обновления темы и сторонних модулей.
Три способа подбора шин
По типоразмеру, по марке и модели автомобиля и отдельный подбор разношироких комплектов, которого обычный фильтр собрать не может.
Цены всех складов в карточке
Предложения по городам сортируются по цене, лучшее отмечено; год выпуска, остаток и страна — у каждого склада свои.
Структура каталога и адреса
Корень «Шины», четыре типа транспорта, 15 сезонных посадочных страниц и постоянный адрес у каждой карточки вместо ссылки с номером товара.
Ускорение в пять раз
Индексы, кеш списков и движка, прогрев после ночного обмена, отложенная загрузка картинок и свои шрифты без обращений к Google.
Ночной обмен переписан
74 секунды вместо четырёх заданий подряд, защита от пустого прайса и отказ от удаления товаров — вернувшаяся позиция получает прежний адрес.
Что внутри
- OpenCart 3
- PHP
- MySQL
- собственный слой стилей
- ocmod
- SEO-структура
С чего начинали
Первым делом разобрали журналы и базу — до единой правки в коде. Файл ошибок занимал 6,4 ГБ, и 99,98 % его содержимого оказалось одной повторяющейся ошибкой в генераторе товарного фида: около 1,1 миллиона одинаковых записей. За ней в логе пряталось всё остальное — в том числе ошибки подборщика шин и Новой Почты, которые как раз ломали покупателю сценарий заказа.
В базе 7,1 ГБ из 7,3 занимала таблица сессий с 26,8 миллионами просроченных строк. Причина оказалась в одной строке драйвера: срок жизни сессии сравнивался с датой как с числом, поэтому уборщик не удалял ничего и никогда. По той же причине сессии не истекали вовсе.
Отдельно проверили, что доступно из интернета. В служебной папке лежал скрипт, который очищает товарные таблицы шестью запросами, и открывался он по прямой ссылке кем угодно. Папку закрыли двумя рубежами, а сами скрипты научили запускаться только из командной строки.
| Что смотрели | Было | Стало |
|---|---|---|
| Ответ главной страницы | 1–5,7 секунды | 0,2 секунды |
| Витрина каталога | 4,5 секунды | 1,0 секунды |
| Страница фильтра | 3,7–5,4 секунды | 0,4–1,3 секунды |
| Ночное обновление каталога | не укладывалось в четыре задания подряд | 74 секунды одним проходом |
| Журнал ошибок | 6,4 ГБ, 1,1 млн одинаковых записей | пустой |
| Таблица сессий | 7,1 ГБ, 26,8 млн просроченных строк | чистится ночью, окно 20 дней |
| Адрес карточки товара | /shiny?product_id=1530939, без canonical | /continental-wintercontact-ts-870p-225-55-r17-97h |
| Карта сайта | отсутствовала | около 35 000 адресов, собирается каждую ночь |
| Страницы брендов | 614 пустых отдавали 200, а 68 рабочих — 404 | пустые скрываются сами, рабочие открыты |
| Разделы каталога | все шины в одном разделе, мотошины выключены | четыре типа транспорта и 15 сезонных страниц |
| Отделения Новой Почты | поиск города не работал вообще | работает |


Новый вид поверх работающего магазина
Переписывать тему с нуля мы не стали, и это было осознанное решение, а не экономия. В теме 13 собственных модулей, а 31 из 39 установленных в магазине патчей правит именно её шаблоны: замена темы означала бы переделку всего магазина разом и остановку продаж на недели.
Вместо этого завели собственный слой стилей, который подключается последним и ничего в теме не затирает. Там, где правки касались шаблонов, они вносились и в оригинал, и в собранную движком копию — иначе первое же нажатие «обновить модификации» в админке стёрло бы всё без единой ошибки в журнале.
Карточка товара
Собрана заново: название в две строки — бренд с моделью и отдельно типоразмер, логотип бренда, метка наличия, характеристики плашками под фотографией, блоки с описанием, европейской этикеткой, похожими моделями и отзывами.
Склады и цены по городам
Вместо таблицы — плашки: город, год выпуска, остаток и страна с флагом у каждого предложения. Они отсортированы по цене, лучшее отмечено, а выбор склада подставляется в форму заказа, чтобы покупка не ушла не с того города.
Шапка и мегаменю
Поиск с подсказками, два номера со значками операторов, переключатель языка и ночного режима, плашки ходовых диаметров. В мегаменю — типы транспорта, сезоны, бренды и типоразмеры одним экраном.
Боковой фильтр
Списки размеров с поиском внутри, разделением на ходовые и остальные и честными счётчиками. Отдельная галочка включает режим разношироких шин с двумя осями.
Тёмная тема
Доведена по всему сайту, а не только на главной: ссылки и кнопки, подложки, фотографии товаров, текстовые страницы, фильтр, всплывающие окна и оформление заказа. Расхождения искали обходом страниц, а не на глаз.
Адаптив
Ниже 1200 пикселей фильтр уходит в выдвижную панель, а витрина занимает ширину экрана; ниже 992 шапка перестраивается в две строки. На устройствах без мыши мегаменю открывается нажатием — раньше оно мелькало и сразу уходило на страницу каталога.
Оформление заказа
Одностраничное оформление приведено к стилю сайта: формы слева, корзина справа и едет за прокруткой, поля и кнопки в общей геометрии, своя ночная тема. На телефоне корзина идёт первой.
Единая система подсказок
Один механизм на весь сайт: достаточно пометить элемент — и подсказка появится у курсора. Написан без лишних зависимостей и работает на динамически добавленных блоках.


Как покупатель находит свой размер
Шины ищут тремя разными способами, и каждый требует своего механизма. Кто-то переписывает размер с боковины, кто-то знает только марку и год машины, а у части автомобилей спереди и сзади стоят разные шины — такой комплект обычный фильтр каталога собрать не может в принципе, потому что условие «у модели есть обе оси в наличии» относится к модели, а не к товару.
Поэтому подбор сделан тремя входами, и все три доступны с главной, из шапки и из фильтра.
Подбор по типоразмеру
Ширина, высота, диаметр плюс бренд, сезон и шипы. Списки связаны между собой: выбранная ширина оставляет только те высоты и диаметры, которые с ней действительно бывают.
Подбор по автомобилю
Марка, модель, год и двигатель. Результат разложен на заводскую комплектацию и варианты замены, а если у машины разноширокий комплект — он показан одной плашкой с передней и задней осью, а не плоским списком, в котором не разобрать, где перед, а где зад.
Разноширокие комплекты
Отдельная страница подбора: две оси со своими списками и счётчиками моделей, в результате — модель с обеими осями, ценами и кнопкой покупки на каждую. Подбор можно пересобрать прямо на странице.
Европейская этикетка
Расход топлива, сцепление на мокрой дороге и шум вынесены на карточку значками, рядом — окно с расшифровкой. Сами этикетки перенесены к себе и дозагружаются ночью, а не тянутся с чужого сервера при каждом показе.
Модели шин как отдельная сущность
1220 моделей со своими страницами, адресами и текстами. Тексты хранятся отдельно от товаров, поэтому ночная выгрузка их не затирает — это и было главным требованием владельца.
Популярные типоразмеры
Отдельная страница и блок на главной: в каждом размере — сезоны, что есть в наличии, и бренды этого размера.
Уведомления в Telegram
Новый заказ, обратный звонок, заявка «нашли дешевле», сообщение с формы, отзыв, подписка и регистрация. В заказе — состав со ссылками на товары, доставка, оплата и телефон в том виде, который Telegram сам делает кликабельным.
Защита форм от ботов
После того как в заявки полетел спам, поставили четыре независимых заслона: невидимое поле-ловушку, метку открытия формы, ограничение частоты и маску номера. Все отвечают одинаковой ошибкой, чтобы по ответу нельзя было понять, какой сработал.
Доставка и оплата
Починен поиск города и выбор отделения Новой Почты — он не работал вообще, покупатель всегда видел «не найдено». Наличные и терминал доступны только при самовывозе, способы оплаты упорядочены.

Где магазин терял секунды
Владелец пожаловался на задержку в три-четыре секунды при переходе на главную. Замер показал разброс от одной до 5,7 секунды, и причина нашлась быстро: шесть запросов, которые наполняют списки в блоке подбора, выполнялись заново на каждой странице, где этот блок есть, и вместе занимали 4,26 секунды. Они перебирали таблицу атрибутов на 1,17 миллиона строк.
Лечение оказалось в три шага: составной индекс на таблицу атрибутов, суточный кеш списков (данные меняются только после ночного обмена, держать их живыми незачем) и прогрев кеша в конце ночного обновления — чтобы пересборку не оплачивал первый утренний посетитель.
Отдельная находка: кеш самого движка писался, но не читался — в библиотеке кеша стояло условие, по которому записи отдавались только для справочника городов. Чтение вернули, а сброс повесили на конец ночного обмена. Это и дало основной выигрыш по всем страницам сразу.
- Ночной обмен переписан: полный прогон за 74 секунды вместо четырёх заданий подряд, память 59 МБ вместо сотен, поиск товаров внутри прогона — 3 секунды вместо 85.
- Два составных индекса на таблицу товаров: план запроса изменился с перебора 17 тысяч строк на выборку одной.
- Справочник атрибутов перечитывался запросом на каждый атрибут каждого товара — около 190 тысяч лишних запросов за прогон. Заменён кешем в памяти.
- Отложенная загрузка картинок проставлена в шаблонах — 57 тегов; на главной откладывается 34 изображения из 101, и больше всего выигрывает меню с логотипами брендов.
- Шрифт перенесён к себе: 10 файлов по языковым подмножествам вместо запроса к шрифтам Google, которого ждала каждая страница.
- Ночная чистка сессий порциями по 50 тысяч строк, с собственным индексом и ограничением по времени — таблица больше не растёт.
| Страница | Было | Стало |
|---|---|---|
| Главная | 1,2 с | 0,2 с |
| Витрина каталога | 4,5 с | 1,0 с |
| Страница фильтра | 3,7–5,4 с | 0,4–1,3 с |
| Карточка товара | 0,9–3,9 с | 0,37 с |
| Первая отрисовка в браузере | 6,3 с | 1,8 с |
| Полная загрузка главной | 8,4 с | 3,5 с |
Структура, адреса и индексация
Главной SEO-проблемой были не тексты, а адреса. Карточка открывалась как /shiny?product_id=1530939, причём префикс зависел от того, откуда пришёл посетитель, canonical не было вовсе, а ночной обмен удалял выбывшие товары и заводил вернувшиеся заново — с новым номером. За восемь месяцев было израсходовано около 623 тысяч номеров при 17 тысячах товаров в каталоге; 42 % каталога пересоздавалось в течение месяца. Проиндексированные страницы просто отмирали.
Три изменения пришлось делать одной связкой, по отдельности они не работают: обмен перестал удалять товары, адрес стал собираться из того, что не меняется, и выданный адрес больше не пересчитывается.
Постоянный адрес у карточки
Собирается из замороженного слага модели и типоразмера, а не из названия, которое поставщик правит (274 правки за восемь прогонов). Выдаётся один раз и хранится в собственном реестре. Старые адреса с номером товара отдают 301 на короткий.
Товары больше не удаляются
Выбывшая позиция остаётся с нулевым остатком и пропадает из списков и фильтров; вернулась в прайс — вернулась с тем же адресом. Не появлялась год — выводится из каталога и отдаёт 410 Gone: для поисковика это «страницы больше не будет».
Структура каталога
Корень «Шины», под ним четыре типа транспорта, а сезоны — отдельные посадочные страницы со своими заголовками и метатегами, 15 штук. Схема обошлась без правки стороннего модуля фильтра, поэтому переживёт его обновление.
Белый список индексации
Индексируются корень, четыре раздела и сезонные страницы; любые другие комбинации фильтров работают для покупателя, но в индекс не идут. Заодно исправлен запрет обхода ссылок, из-за которого робот не доходил до товаров.
Бренды приведены в порядок
Из 731 бренда товары были у 117: 614 пустых страниц отдавали код 200 с пустым содержимым. Пустые теперь скрываются автоматически, а 68 брендов с товарами, которые годами отдавали 404 из-за отсутствующей записи в базе, снова открываются.
Своя карта сайта
Штатный модуль был выключен, а сервер всё равно перенаправлял на него — отсюда пустой ответ. Написан свой генератор: около 35 тысяч адресов в нескольких файлах, сборка в конце ночного обмена.
robots.txt под новую структуру
Каталог, бренды и информационные страницы открыты; служебные маршруты, корзина, оформление, сортировки и постраничная навигация закрыты, как и все 28 параметров фильтра.
Редиректы и фид
Все адреса прежнего сайта прогнаны запросами: ни один не уходит в 404. В товарном фиде для Google треть позиций не выгружалась — причину нашли и устранили.
Как шла работа
Магазин работает и приносит заказы каждый день, поэтому правила были простые: ничего не проверять на боевом сайте и не останавливать продажи.
Разбор
Журналы, база, код ночного обмена, структура каталога и то, что доступно из интернета. До первой правки стало понятно, что чинить в первую очередь, а что только кажется проблемой.
Копия магазина
Полная копия с отдельной базой, закрытая паролем и запретом индексации, с отключённой аналитикой и переписанными ссылками на боевой домен. Все работы шли на ней.
Итерации по спискам замечаний
Владелец смотрел копию и присылал замечания списками, мы разбирали их по порядку. Каждая правка проверялась на живых данных, перед каждой — резервная копия.
Переключение
Заглушка с кодом 503 и заголовком «вернёмся через десять минут», финальная синхронизация заказов уже под заглушкой — она подобрала два заказа, пришедших за семнадцать минут до переключения, — обмен папок, настройка и проверка. Простой составил 11 минут.
Доводка после запуска
Возвращена аналитика, переписан robots.txt, проверены все редиректы, собрана карта сайта, настроена ночная чистка сессий и прогрев кеша. Старая версия сохранена отдельно и закрыта от поисковиков.
Что обычно спрашивают об этом проекте
Потому что в теме магазина 13 собственных модулей, а 31 из 39 установленных патчей правит именно её шаблоны. Замена темы означала бы переписать магазин целиком и остановить продажи на недели. Собственный слой стилей и точечные правки дали тот же результат по внешнему виду, но без простоя.
Нет. Всё делалось на полной копии с отдельной базой, боевой сайт продолжал принимать заказы. Остановка была одна — 11 минут в момент переключения, под заглушкой с кодом 503, которая объясняет поисковику, что это временно.
Ничего. Адрес собирается из слага модели и типоразмера, выдаётся один раз и больше не пересчитывается, а выбывшие товары не удаляются — они просто перестают показываться. Вернулась позиция в прайс — открывается по прежнему адресу.
Потому что пока в них нет текстов. Сущность, адреса, страницы и раздел админки готовы, 1220 моделей заведены. Владелец наполняет их описаниями — после этого страницы открываются для индекса и попадают в карту сайта следующей же ночью.
Около трёх недель плотной работы — от разбора логов до переключения на новую версию, плюс доводка после запуска. Большая часть времени ушла не на вёрстку, а на структуру каталога, адреса товаров и ночной обмен.
Да, подход не зависит от CMS: разбор узких мест, копия для работ, свой слой поверх существующего кода и переключение с минимальным простоем. Мы так же работаем с WordPress, WooCommerce и самописными каталогами.
Нужен похожий проект?
Разберём вашу задачу, покажем варианты решения и назовём сроки со сметой. Бесплатно и без обязательств.
Смотрите также

NIO Украина
Сайт представителя электромобилей NIO и ONVO в Украине: презентация модельного ряда и приём заявок на покупку.

Voyah Украина
Сайт официального импортёра Voyah: восемь моделей, дилеры в шести городах, заявка на тест-драйв.

Хоттабич
Трёхъязычный интернет-магазин ковров и штор: каталог с фильтрами, избранное, корзина, услуги и блог.