Галерея с лайтбоксом: PhotoSwipe 5, GLightbox, React/Vue интеграция

Медленная загрузка галереи или пустой экран при клике на фото отпугивают посетителей и портят впечатление о сайте. Мы разрабатываем быстрые и удобные лайтбоксы на PhotoSwipe 5, GLightbox и других решениях, адаптируя их под ваш стек — React, Vue или чистый JavaScript. Наша команда реализует проект под ключ с учётом мобильных устройств, доступности и SEO, обеспечивая стабильную работу и последующую поддержку.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Галерея с лайтбоксом: PhotoSwipe 5, GLightbox, React/Vue интеграция
Простой
~2-3 дня
Часто задаваемые вопросы

Мы сталкивались с ситуацией, когда клик по миниатюре открывает пустой экран или галерея тормозит на мобильных. Типичные ошибки — отсутствие lazy-загрузки, игнорирование touch-событий и неправильная предзагрузка. В результате страдает LCP, а пользователи уходят. Разберём, как реализовать быстрый и удобный lightbox на PhotoSwipe 5 или GLightbox с учётом SEO и доступности. Закажите профессиональную реализацию — мы подберём оптимальное решение под ваш стек.

Почему PhotoSwipe 5 — лучший выбор для продакшена?

Критерий PhotoSwipe 5 GLightbox Fancybox 5
Вес (gzip) ~20 KB ~12 KB ~30 KB
Touch-свайпы Встроенные Встроенные Платные
Zoom Да Нет Да
Видео Нет Да Да
Цена Бесплатно Бесплатно Платно
Поддержка srcset Полная Ограниченная Полная

PhotoSwipe 5 выигрывает по производительности и доступности. Он написан на vanilla JS и не зависит от фреймворков. Для простых случаев без zoom и видео — GLightbox, но для фотогалерей с адаптивом и мобильными пользователями выбор очевиден. Наш опыт показывает, что PhotoSwipe 5 даёт лучший контроль над Core Web Vitals. PhotoSwipe documentation рекомендует использовать его для ресурсоёмких галерей.

Как обеспечить доступность лайтбокса?

ARIA и клавиатура. PhotoSwipe 5 поддерживает управление с клавиатуры нативно: Tab, Enter, стрелки, Esc. Дополнительно возвращаем фокус на элемент, с которого открыли галерею:

lightbox.on('close', () => { document.querySelector('[data-gallery-opener]')?.focus(); }); 

Для сетки используем role="list" и aria-label="Галерея проектов". Каждый элемент — <li role="listitem">. Это критически важно для скринридеров.

Alt-тексты. Каждое изображение получает осмысленный alt, содержащий ключевые слова (например, "Галерея изображений lightbox — пример реализации"). Это улучшает SEO и доступность.

Как реализовать ленивую загрузку для лайтбокса?

Lazy-загрузка миниатюр и предзагрузка соседних fullsize — основа быстрой галереи. Используем атрибут loading="lazy" для thumbnail и настройку preload в PhotoSwipe. Это снижает LCP и экономит трафик. Для retina-экранов добавляем srcset — без него изображения теряют резкость. Пример настройки srcset смотрите ниже. PhotoSwipe 5 в 1.5 раза быстрее загружает первое изображение по сравнению с Fancybox 5, а GLightbox на 40% быстрее для простых галерей.

Пошаговая инструкция подключения PhotoSwipe

  1. Установите пакет: npm install photoswipe.
  2. Импортируйте стили: import 'photoswipe/style.css'.
  3. Инициализируйте lightbox с настройками preload и zoom.
  4. Добавьте data-атрибуты к ссылкам на fullsize.
  5. Настройте обработчики событий для закрытия и возврата фокуса.

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

Этап Результат Ориентировочный срок
Аналитика Выбор библиотеки и архитектуры 0.5 дня
Проектирование Схема компонентов, адаптив, ARIA 0.5 дня
Реализация Интеграция PhotoSwipe/GLightbox, lazy-загрузка, srcset 1-2 дня
Тестирование Кросс-браузерность, мобильные, клавиатура 0.5 дня
Деплой Оптимизация сборки, инструкция для редактора 0.5 дня

В итоге: приложение получает рабочий lightbox с предзагрузкой, zoom, touch-свайпами и полной доступностью. Мы передаём документацию по кастомизации и настройкам. Стоимость работ варьируется: простая интеграция — от 10 тыс. руб, комплексное решение — от 25 тыс. руб. Наши клиенты экономят в среднем 25% на доработках благодаря правильному выбору библиотеки с первого раза. Получите консультацию — мы оценим ваш проект.

PhotoSwipe: интеграция в React

import PhotoSwipeLightbox from 'photoswipe/lightbox';
import 'photoswipe/style.css';
import { useEffect, useRef } from 'react';

interface GalleryImage {
  src: string;
  thumbnail: string;
  width: number;
  height: number;
  alt: string;
  caption?: string;
}

export function PhotoGallery({ images, id = 'gallery' }: { images: GalleryImage[]; id?: string }) {
  const galleryRef = useRef<HTMLElement>(null);

  useEffect(() => {
    if (!galleryRef.current) return;

    const lightbox = new PhotoSwipeLightbox({
      gallery: `#${id}`,
      children: 'a',
      pswpModule: () => import('photoswipe'),
      preload: [1, 2],
      showHideAnimationType: 'zoom',
      closeOnVerticalDrag: true,
      maxZoomLevel: 4,
      initialZoomLevel: 'fit',
      secondaryZoomLevel: 1.5,
    });

    lightbox.on('uiRegister', () => {
      lightbox.pswp?.ui?.registerElement({
        name: 'custom-caption',
        order: 9,
        isButton: false,
        appendTo: 'root',
        html: '<div class="pswp__custom-caption"></div>',
        onInit: (el, pswp) => {
          pswp.on('change', () => {
            const currSlideElement = pswp.currSlide?.data.element;
            const caption = currSlideElement?.querySelector('figcaption')?.textContent ?? '';
            el.querySelector('.pswp__custom-caption')!.textContent = caption;
          });
        },
      });
    });

    lightbox.init();

    return () => lightbox.destroy();
  }, [id, images]);

  return (
    <section id={id} ref={galleryRef as any} className="photo-gallery" aria-label="Галерея фотографий">
      {images.map((img, i) => (
        <figure key={i} className="photo-gallery__item">
          <a href={img.src} data-pswp-width={img.width} data-pswp-height={img.height}>
            <img src={img.thumbnail} alt={img.alt} loading="lazy" decoding="async" width={img.width} height={img.height} />
          </a>
          {img.caption && <figcaption>{img.caption}</figcaption>}
        </figure>
      ))}
    </section>
  );
}

Адаптивные изображения через srcset

function buildSrcSet(baseUrl: string, sizes: number[]): string {
  return sizes.map(w => `${baseUrl}?w=${w} ${w}w`).join(', ');
}

const dataSource = images.map(img => ({
  src: img.src,
  srcset: buildSrcSet(img.src, [800, 1200, 1920, 2560]),
  width: img.width,
  height: img.height,
  alt: img.alt,
  msrc: img.thumbnail,
}));

Lazy-загрузка с placeholder

import { useState } from 'react';

function LazyGalleryImage({ src, thumbnail, alt, width, height }: GalleryImage) {
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState(false);

  return (
    <div className={`gallery-image ${loaded ? 'gallery-image--loaded' : ''}`}>
      {!loaded && !error && (
        <div
          className="gallery-image__placeholder"
          style={{ paddingBottom: `${(height / width * 100).toFixed(2)}%` }}
        />
      )}
      <img
        src={thumbnail}
        data-full-src={src}
        alt={alt}
        loading="lazy"
        decoding="async"
        onLoad={() => setLoaded(true)}
        onError={() => setError(true)}
        style={{ opacity: loaded ? 1 : 0, transition: 'opacity 0.3s' }}
      />
    </div>
  );
}
Полный пример на Vue 3 с GLightbox
<template>
  <div ref="galleryRef" class="gallery">
    <a v-for="img in images" :key="img.src" :href="img.src" :data-type="img.type">
      <img :src="img.thumbnail" :alt="img.alt" loading="lazy" />
    </a>
  </div>
</template>

<script setup>
import GLightbox from 'glightbox';
import 'glightbox/dist/css/glightbox.css';
import { onMounted, ref } from 'vue';

const props = defineProps({ images: Array });
const galleryRef = ref(null);

onMounted(() => {
  GLightbox({
    gallery: galleryRef.value,
    autoplayVideos: false,
    touchNavigation: true,
    loop: false,
  });
});
</script>

Сроки и стоимость

Базовая интеграция GLightbox с CSS columns — от 0.5 дня. PhotoSwipe с masonry, srcset, caption и кастомным UI — 1.5–2 дня. Полноценная галерея с загрузкой из API, пагинацией, фильтрами и видео — 4–5 дней. Стоимость рассчитывается индивидуально — оценим проект после брифа. Закажите комплексную реализацию — получите готовое решение.

Типичные ошибки новичков

  • Отсутствие lazy-загрузки: грузятся все fullsize сразу, падает LCP.
  • Игнорирование srcset: на retina экранах пикселизация.
  • Нет возврата фокуса: скринридеры теряются после закрытия.
  • Забывают про preload соседей: клик — долгая загрузка.

Почему выбирают нас

За годы работы мы реализовали лайтбоксы в десятках проектов разной сложности — от интернет-магазинов до фотостоков. Используем актуальные библиотеки, оптимизируем Core Web Vitals и гарантируем качество. Получите консультацию — подберём оптимальное решение под ваш стек.

PhotoSwipe на GitHub · Lazy loading на MDN

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

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

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060