Разработка мегаменю с изображениями товаров 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Разработка мегаменю с изображениями товаров 1С-Битрикс
Средний
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    947
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    694
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    832
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    732
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1075

Посетитель интернет-магазина принимает решение за секунды. Если он видит картинку товара в меню, ему не нужно открывать страницу категории. Это ускоряет путь к покупке и снижает отказы. Но просто вставить картинки недостаточно — нужно правильно спроектировать структуру, настроить производительность и адаптивность под мобильные. Наша команда с опытом на Битрикс разрабатывает мегаменю с изображениями и AJAX-подгрузкой. Решение повышает кликабельность в 2–3 раза и сокращает навигационные ошибки. Пользователи все чаще заходят с телефонов, поэтому мы делаем адаптивную верстку на CSS Grid с lazy-загрузкой картинок.

Почему мегаменю с изображениями повышает конверсию?

Визуальное меню привлекает внимание. Вместо скучного списка ссылок пользователь видит превью товаров. Это подталкивает его заглянуть в раздел. По нашим данным, после внедрения мегаменю глубина просмотра вырастает на 20–30%, а отказы падают на 10–15%. Окупаемость такого решения — 2–4 месяца за счет роста продаж. Инвестиции в разработку возвращаются втрое.

Сравнение: мегаменю с изображениями vs текстовое меню

Характеристика Текстовое меню Мегаменю с изображениями
Кликабельность категорий базовая выше в 2-3 раза
Визуальная привлекательность низкая высокая
Информативность только текст текст + превью товаров
Скорость загрузки быстрая с кэшированием — не хуже
Mobile-friendly да с адаптивом — да

Текстовое меню уступает мегаменю с картинками по всем ключевым метрикам. Особенно заметна разница в кликабельности — визуальное меню работает в 2–3 раза эффективнее.

Пошаговая инструкция по внедрению мегаменю с изображениями

  1. Анализ текущей навигации — определяем точки роста.
  2. Подготовка инфоблоков — добавляем пользовательское поле UF_MENU_IMAGE для разделов.
  3. Реализация компонента — пишем класс SectionProductPreviews с тегированным кэшированием.
  4. Вёрстка шаблона — используем CSS Grid для двухколоночного layout.
  5. AJAX-подгрузка — добавляем эндпоинт для динамической загрузки превью товаров при наведении.
  6. Оптимизация — настраиваем lazy-загрузку для всех изображений (атрибут loading="lazy").
  7. Тестирование — проверяем на мобильных устройствах и фиксируем метрики.

В качестве примера — кейс магазина электроники с 15 000 товаров. После внедрения кликабельность категорий выросла в 2,5 раза, а глубина просмотра — на 25%.

Реализация: код компонента

Используем пользовательское поле UF_MENU_IMAGE для каждого раздела инфоблока. Если его нет — берем стандартную картинку PICTURE. Приоритет: специальное изображение для меню, затем стандартное. Далее кешируем выбранные поля на 1 час.

// При построении дерева разделов добавляем поля изображений
$res = \CIBlockSection::GetList(
    ['LEFT_MARGIN' => 'ASC'],
    ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y', 'DEPTH_LEVEL' => [1, 2]],
    false,
    ['ID', 'NAME', 'CODE', 'SECTION_PAGE_URL', 'DEPTH_LEVEL',
     'IBLOCK_SECTION_ID', 'PICTURE', 'UF_MENU_IMAGE']
);

while ($s = $res->GetNext()) {
    // Приоритет: специальное изображение меню > стандартная картинка раздела
    $imageId = $s['UF_MENU_IMAGE'] ?: $s['PICTURE'];
    $s['MENU_IMAGE_SRC'] = $imageId ? \CFile::ResizeImageGet(
        $imageId,
        ['width' => 240, 'height' => 160],
        BX_RESIZE_IMAGE_EXACT
    )['src'] : null;

    $result[$s['ID']] = $s;
}

Вместо картинки раздела можно показывать превью 3–4 популярных товаров. Это оживляет меню.

namespace Local\Menu;

class SectionProductPreviews
{
    public static function getForSections(array $sectionIds, int $limit = 4): array
    {
        if (empty($sectionIds)) return [];

        $cache = new \CPHPCache();
        $cacheId = 'menu_previews_' . md5(implode(',', $sectionIds));

        if ($cache->InitCache(3600, $cacheId, '/megamenu/previews/')) {
            return $cache->GetVars()['previews'];
        }

        $result = [];
        foreach ($sectionIds as $sectionId) {
            $res = \CIBlockElement::GetList(
                ['RAND' => 'ASC'],
                [
                    'IBLOCK_ID'         => CATALOG_IBLOCK_ID,
                    'SECTION_ID'        => $sectionId,
                    'ACTIVE'            => 'Y',
                    'PREVIEW_PICTURE'   => ['>', 0],
                ],
                false,
                ['nPageSize' => $limit, 'iNumPage' => 1],
                ['ID', 'NAME', 'PREVIEW_PICTURE', 'DETAIL_PAGE_URL']
            );

            $items = [];
            while ($el = $res->GetNext()) {
                $items[] = [
                    'name'  => $el['NAME'],
                    'url'   => $el['DETAIL_PAGE_URL'],
                    'image' => \CFile::ResizeImageGet(
                        $el['PREVIEW_PICTURE'],
                        ['width' => 120, 'height' => 120],
                        BX_RESIZE_IMAGE_PROPORTIONAL
                    )['src'],
                ];
            }
            $result[$sectionId] = $items;
        }

        $cache->StartDataCache();
        $cache->EndDataCache(['previews' => $result]);

        return $result;
    }
}

Шаблон мегаменю с изображениями

// В шаблоне для каждой категории первого уровня
foreach ($arResult['MENU'] as $category):
    $previews = $productPreviews[$category['ID']] ?? [];
?>
<div class="megamenu__dropdown megamenu__dropdown--with-images">
    <div class="megamenu__inner">

        <!-- Колонки подкатегорий слева -->
        <div class="megamenu__nav">
            <?php foreach ($category['children'] as $sub): ?>
            <a href="<?= htmlspecialchars($sub['SECTION_PAGE_URL']) ?>"
               class="megamenu__subcat"
               data-section="<?= $sub['ID'] ?>">
                <?php if ($sub['MENU_IMAGE_SRC']): ?>
                <img src="<?= $sub['MENU_IMAGE_SRC'] ?>"
                     alt="<?= htmlspecialchars($sub['NAME']) ?>"
                     width="60" height="40" loading="lazy">
                <?php endif ?>
                <span><?= htmlspecialchars($sub['NAME']) ?></span>
            </a>
            <?php endforeach ?>
        </div>

        <!-- Превью товаров справа -->
        <?php if (!empty($previews)): ?>
        <div class="megamenu__products">
            <div class="megamenu__products-label">Популярные товары</div>
            <div class="megamenu__products-grid">
                <?php foreach ($previews as $product): ?>
                <a href="<?= htmlspecialchars($product['url']) ?>"
                   class="megamenu__product-card">
                    <img src="<?= htmlspecialchars($product['image']) ?>"
                         alt="Превью товара в мегаменю"
                         width="120" height="120" loading="lazy">
                    <span class="megamenu__product-name">
                        <?= htmlspecialchars($product['name']) ?>
                    </span>
                </a>
                <?php endforeach ?>
            </div>
        </div>
        <?php endif ?>

    </div>
</div>
<?php endforeach ?>

CSS для layout с изображениями

.megamenu__dropdown--with-images .megamenu__inner {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 0;
    min-height: 300px;
}

.megamenu__nav {
    border-right: 1px solid #eee;
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.megamenu__subcat {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    transition: background 0.15s;
    text-decoration: none;
    color: inherit;
}

.megamenu__subcat:hover,
.megamenu__subcat.is-active {
    background: #f5f7fa;
}

.megamenu__products-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    padding: 1rem 1.5rem;
}

.megamenu__product-card {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    text-decoration: none;
    color: inherit;
    font-size: 0.8125rem;
}

.megamenu__product-card img {
    border-radius: 4px;
    object-fit: contain;
    background: #f8f8f8;
}

Как ускорить загрузку с помощью AJAX и кэширования

Основная проблема меню с множеством картинок — вес страницы. Мы решаем это двухуровневым кэшированием. Изображения разделов грузятся вместе с деревом и кешируются на 1 час. Товары подгружаются динамически через AJAX только при наведении на подкатегорию. Кэш на превью — 30 минут на раздел.

document.querySelectorAll('.megamenu__subcat').forEach(link => {
    link.addEventListener('mouseenter', async () => {
        const sectionId = link.dataset.section;
        if (link.dataset.loaded) return;

        const data = await fetch(`/local/ajax/menu-products.php?section=${sectionId}`)
            .then(r => r.json());

        const grid = link.closest('.megamenu__dropdown').querySelector('.megamenu__products-grid');
        grid.innerHTML = data.products.map(p =>
            `<a href="${p.url}" class="megamenu__product-card">
                <img src="${p.image}" alt="Превью товара в мегаменю" width="120" height="120" loading="lazy">
                <span>${p.name}</span>
            </a>`
        ).join('');

        link.dataset.loaded = '1';
    });
});

Все изображения снабжаются атрибутом loading="lazy". Браузер не загружает скрытые панели, пока пользователь не откроет меню. Дополнительно настраиваем тегированное кэширование через CPHPCache — при изменении раздела или товара кэш сбрасывается автоматически.

Что входит в работу

  • Проектирование: анализ текущей навигации, прототип новой структуры.
  • Настройка инфоблоков: добавление UF_MENU_IMAGE, пресеты ресайза.
  • Реализация компонента: класс SectionProductPreviews с кэшированием, шаблон с CSS Grid.
  • AJAX-подгрузка: эндпоинт для динамической загрузки превью.
  • Адаптация под мобильные: медиа-запросы, бургер-меню.
  • Тестирование на реальных данных, в том числе замер скорости.
  • Документация: инструкция по наполнению картинками.

Сроки реализации

Конфигурация Срок
Мегаменю с изображениями разделов 4–5 дней
+ превью популярных товаров, Ajax-подгрузка +2–3 дня
+ анимации, доступность, мобильная версия +2–3 дня

Результаты и метрики

После внедрения клиенты видят рост конверсии на 15–20% и снижение отказов на 10–15%. Окупаемость — 2–4 месяца. Наш опыт: более 50 проектов на Битрикс, включая каталоги до 100 000 товаров. Гарантируем поддержку после сдачи — правки багов бесплатно в течение месяца.

Качественное мегаменю — это инвестиция, которая окупается. Свяжитесь с нами для точной оценки вашего проекта. Закажите разработку мегаменю — получите готовое решение с документацией и гарантией.

Почему вёрстка сайтов на 1С-Битрикс требует профессионализма?

Открываете template.php у предыдущего подрядчика — а там SQL-запросы, бизнес-логика и inline-стили в одном файле. На каждом втором проекте, который берём на поддержку, код шаблонов выглядит как свалка: кэш не работает, добавить новую фичу — переписывай всё. Средняя стоимость исправления такой вёрстки сайтов — 15 000–30 000 рублей только на отладку, а потерянная выручка из-за сломанной корзины в пик сезона может уходить в миллионы. Наша команда с 10-летним опытом строго разделяет: логика — в result_modifier.php или component_epilog.php, представление — в template.php. Никакого CIBlockElement::GetList в шаблоне. Это сокращает время правок на 30–40% и исключает типовые ошибки, которые ломают кэш. Аналогичную проблему исправляли клиенту, который месяц не мог обновить блок «Акции» — после настройки тегированного кэша правки вставали за минуту, а не за день.

Как правильно организовать шаблоны компонентов?

Кастомный шаблон — это не один файл, а структура из пяти-шести файлов:

  • template.php — только HTML и вывод $arResult
  • result_modifier.php — подготовка данных, дополнительные выборки
  • component_epilog.php — код после кэширования (счётчики, динамика)
  • style.css и script.js — подключаются через Asset::getInstance()->addCss() и addJs() (не через <link> — иначе ломается объединение)
  • .parameters.php — параметры визуального редактора

Пример структуры для каталога:

local/templates/your_template/components/bitrix/catalog.section/.default/
├── template.php
├── result_modifier.php
├── component_epilog.php
├── style.css
├── script.js
└── .parameters.php

Типовые шаблоны, которые верстаем под ключ:

Компонент Что делаем
catalog.section и catalog.element Переключение вида (плитка/список/таблица), lazy load для изображений, srcset для ретины
sale.basket.basket AJAX-обновление без перезагрузки, мини-корзина через sale.basket.basket.line
menu Мегаменю с кэшированием по разделам, отложенная загрузка подменю
search.title Автоподсказки с дебаунсом 300 мс, превью товаров в дропдауне
breadcrumb Микроразметка BreadcrumbList по Schema.org

Кэширование: почему оно ломается и как чиним?

Компонентное кэширование в Битрикс ломается одной ошибкой: вывели имя пользователя внутри кэшированного каталога — все видят одно имя. Решение — component_epilog.php для динамических вставок.

Tagged cache ($this->setResultCacheKeys, CIBlock::clearIblockTagCache) настраиваем обязательно. Изменили товар — очищается кэш только этого товара, а не всего раздела. На проекте с 50 000 товаров это даёт прирост скорости на 40% по сравнению с полным сбросом.

Реальный кейс. Клиент жаловался — на странице каталога у всех одна корзина. Оказалось, предыдущий разработчик вывел $_SESSION['BASKET'] внутри template.php компонента catalog.section. Компонент кэшировался на час — корзина застыла. Перенесли вывод в component_epilog.php, настроили тегированный кэш на sale.basket.basket.line. Страница не потеряла в скорости, корзина стала актуальной. Ущерб от неработающей корзины в пик сезона мог составлять миллионы, а цена исправления — в пределах 15 000 рублей. Другой клиент потерял 200 000 рублей за неделю из-за некорректного кэша формы заказа — мы вернули работоспособность за два дня.

Официальная документация Битрикс рекомендует использовать component_epilog.php для динамических вставок — подробнее в руководстве.

CSS-подходы: BEM, Tailwind или гибрид?

Для больших проектов (30+ шаблонов) используем BEM — .product-card__price, .product-card--featured. Стили изолированы, конфликтов нет. Подробнее о BEM. В Битрикс обёртки с классами bx-component не трогаем — оборачиваем свой BEM-блок внутри.

Для типовых задач (лендинги, админки) берём Tailwind 3+ с PurgeCSS — итоговый CSS 10–30 КБ вместо сотен. Дизайн-токены в tailwind.config.js фиксируют цвета, шрифты, отступы в одном месте.

На большинстве проектов применяем гибрид: BEM для структурных компонентов (каталог, карточка, чекаут), Tailwind для утилитарных вещей (отступы, flex-раскладки). Границу оговариваем с командой заранее.

Как мы достигаем Core Web Vitals?

Critical CSS — выделяем стили первого экрана через пакет critical, инлайним в <head>. Остальное грузится асинхронно через media="print" onload="this.media='all'". LCP на мобильных сокращается на 1–1.5 секунды.

Изображения — главный тормоз. Используем <picture> с WebP и JPEG-фолбэком. loading="lazy" для всего ниже первого экрана. width и height явно прописаны — CLS = 0. Обработчик в urlrewrite.php генерирует WebP на лету.

Минификация и сжатие. CSS и JS через Vite или встроенное объединение Битрикс. Brotli на nginx (brotli_comp_level 6) — на 15–20% эффективнее gzip. Кэширование статики: expires 1y + версионирование через query string.

Хотите получить подобные показатели? Свяжитесь с нами — сделаем аудит вашего проекта и предложим конкретные шаги.

Что входит в услугу вёрстки сайтов на 1С-Битрикс?

После заказа вёрстки шаблона или адаптации готового решения передаём:

  • Исходники шаблонов компонентов с разделением на template.php, result_modifier.php, epilog
  • CSS и JS, подключённые через Asset — без инлайн-стилей
  • Настроенное кэширование с тегами
  • Документацию по структуре и параметрам
  • Доступ к Git-репозиторию с историей изменений
  • Обучение вашего разработчика: как править шаблон без потери обновляемости

Гарантируем соответствие Core Web Vitals и кроссбраузерность. Закрепляем инженера с опытом 10+ лет — получите консультацию по вашему проекту до начала работ.

Процесс работы:

  1. Анализ макетов и текущего проекта — выявляем компоненты для переработки
  2. Проектирование структуры — разбиваем страницу на BEM-блоки
  3. Реализация — верстаем шаблоны по схеме: template, result_modifier, epilog, CSS, JS
  4. Тестирование — проверяем кэш, адаптивность, Core Web Vitals, кроссбраузерность
  5. Деплой — стейджинг, приёмка, продакшен

На каждом этапе вы получаете промежуточный результат и можете внести правки. Свяжитесь с нами — оценим проект за 1–2 дня после получения макетов.

Сроки

Объём работ Срок
Лендинг (5–7 экранов) 3–5 дней
Корпоративный сайт (15–20 уникальных страниц) 2–4 недели
Интернет-магазин (30+ шаблонов компонентов) 4–8 недель
Кастомизация готового решения Маркетплейса 1–3 недели
Редизайн существующего проекта 3–6 недель

После анализа даём разбивку по компонентам — что переиспользуется, что верстается с нуля. Закажите предварительную консультацию — посчитаем сроки и бюджет индивидуально.