Next.js 이미지 로딩 최적화: Swiper 활용하기

강 진성·2025년 4월 18일

이전 포스팅에서 Next.js의 Image 컴포넌트를 활용하여 이미지 로딩 시 발생하는 깜빡임 현상을 해결하는 방법을 소개했다. 하지만 실제 적용 후에도 콘텐츠와 배경 이미지가 처음 로드될 때 약간의 딜레이가 남아있었다. 이번 포스팅에서는 이 문제를 완벽하게 해결하기 위한 개선된 방법을 소개한다.



남아있는 문제점


기존 해결책(Next.js Image 컴포넌트 활용)으로 깜빡임 현상은 많이 개선되었지만, 다음과 같은 문제가 여전히 존재했다:

  1. 콘텐츠와 배경 이미지 사이에 약간의 로딩 시간 차이가 발생

  2. 이미지 전환 시 완벽한 동기화가 이루어지지 않음


새로운 접근법: Swiper로 배경 이미지 처리하기

기존에는 콘텐츠만 Swiper로 관리하고 배경 이미지는 단일 Image 컴포넌트로 처리했다. 이를 개선하기 위해 배경 이미지도 Swiper를 사용하여 관리하는 방식을 도입했다.


배경 이미지용 Swiper 구현

{/* 배경 이미지 Swiper */}
<Swiper
  modules={[Autoplay, EffectFade]}
  effect="fade"
  autoplay={{ delay: 3000, disableOnInteraction: false }}
  loop
  speed={1000}
  slidesPerView={1}
  onSlideChange={(swiper) => setActiveIndex(swiper.realIndex)}
  allowTouchMove={false}
  onSwiper={(swiper) => (bgSwiperRef.current = swiper)}
  className="absolute inset-0 opacity-70 z-0 rounded-2xl"
>
  {shiftedChampions.map((champion, idx) => {
    return (
      <SwiperSlide key={idx}>
        <div className="relative w-full h-[37.5rem]">
          <Image
            src={champion.logo}
            alt={champion.name}
            fill
            priority
            className="object-cover"
          />
        </div>
      </SwiperSlide>
    );
  })}
</Swiper>

콘텐츠용 Swiper 구현

{/* Swiper 콘텐츠 */}
<div className="absolute inset-0 z-10 py-10 px-5">
  <Swiper
    modules={[Navigation, Autoplay]}
    navigation={{
      nextEl: ".swiper-custom-next",
      prevEl: ".swiper-custom-prev",
    }}
    spaceBetween={30}
    slidesPerView={4}
    loop={true}
    autoplay={{ delay: 3000, disableOnInteraction: false }}
    onSlideChange={(swiper) => setActiveIndex(swiper.realIndex)}
    speed={1000}
    allowTouchMove={false}
    onSwiper={(swiper) => (contentSwiperRef.current = swiper)}
    className="w-full h-full z-10"
  >
    {/* 슬라이드 콘텐츠 */}
  </Swiper>
</div>

두 Swiper 동기화하기

두 Swiper 간의 완벽한 동기화를 위해 참조 객체(useRef)를 활용했다.

// 스와이퍼 참조 객체
const contentSwiperRef = useRef(null);
const bgSwiperRef = useRef(null);

// 버튼 동기화
const handleNext = () => {
  contentSwiperRef.current?.slideNext();
  bgSwiperRef.current?.slideNext();
};

const handlePrev = () => {
  contentSwiperRef.current?.slidePrev();
  bgSwiperRef.current?.slidePrev();
};

이 코드를 통해 네비게이션 버튼을 클릭할 때 콘텐츠와 배경 이미지가 동시에 전환되도록 처리했다.



주요 개선 사항


1. EffectFade 모듈 활용
배경 이미지 Swiper에 effect="fade" 옵션을 적용하여 부드러운 전환 효과를 구현했다. 이를 위해 Swiper의 EffectFade 모듈을 import 했다.

2. 동일한 전환 속도 설정
두 Swiper 모두 speed={1000}으로 설정하여 전환 속도를 동일하게 맞췄다. 이를 통해 시각적으로 더 자연스러운 전환이 가능해졌다.

3. 사용자 조작 방지
allowTouchMove={false} 옵션을 통해 사용자가 직접 슬라이드를 조작하는 것을 방지하고, 네비게이션 버튼을 통해서만 슬라이드를 전환할 수 있도록 했다.

4. 이미지 최적화 유지
배경 이미지에도 여전히 Next.js의 Image 컴포넌트를 사용하고 priority 속성을 적용하여 로딩 최적화의 이점을 유지했다.



결과 및 성능 향상

이 개선된 방식을 적용한 결과:

  1. 배경 이미지와 콘텐츠 간의 로딩 시간 차이가 사라졌다.

  2. 이미지 전환 시 깜빡임이 완전히 제거되었다.

  3. fade 효과로 인해 시각적으로 더 부드러운 전환이 가능해졌다.

  4. 네비게이션 버튼을 통한 조작 시 두 요소가 완벽하게 동기화되었다.



결론


Next.js의 Image 컴포넌트와 Swiper를 함께 활용하면 이미지 로딩과 전환 시 발생하는 문제를 효과적으로 해결할 수 있다. 특히 배경 이미지와 콘텐츠를 각각 별도의 Swiper로 관리하고 동기화하는 방식은 사용자 경험을 크게 향상시키는 효과적인 방법이다.

이미지가 많이 사용되는 현대 웹 애플리케이션에서 이러한 최적화는 사용자 만족도를 높이고 웹사이트의 품질을 향상시키는 중요한 요소가 된다.

profile
완전완전완전초보초보초보

0개의 댓글