이전 포스팅에서 Next.js의 Image 컴포넌트를 활용하여 이미지 로딩 시 발생하는 깜빡임 현상을 해결하는 방법을 소개했다. 하지만 실제 적용 후에도 콘텐츠와 배경 이미지가 처음 로드될 때 약간의 딜레이가 남아있었다. 이번 포스팅에서는 이 문제를 완벽하게 해결하기 위한 개선된 방법을 소개한다.
기존 해결책(Next.js Image 컴포넌트 활용)으로 깜빡임 현상은 많이 개선되었지만, 다음과 같은 문제가 여전히 존재했다:
콘텐츠와 배경 이미지 사이에 약간의 로딩 시간 차이가 발생
이미지 전환 시 완벽한 동기화가 이루어지지 않음
기존에는 콘텐츠만 Swiper로 관리하고 배경 이미지는 단일 Image 컴포넌트로 처리했다. 이를 개선하기 위해 배경 이미지도 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 콘텐츠 */}
<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 간의 완벽한 동기화를 위해 참조 객체(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 속성을 적용하여 로딩 최적화의 이점을 유지했다.

이 개선된 방식을 적용한 결과:
배경 이미지와 콘텐츠 간의 로딩 시간 차이가 사라졌다.
이미지 전환 시 깜빡임이 완전히 제거되었다.
fade 효과로 인해 시각적으로 더 부드러운 전환이 가능해졌다.
네비게이션 버튼을 통한 조작 시 두 요소가 완벽하게 동기화되었다.
Next.js의 Image 컴포넌트와 Swiper를 함께 활용하면 이미지 로딩과 전환 시 발생하는 문제를 효과적으로 해결할 수 있다. 특히 배경 이미지와 콘텐츠를 각각 별도의 Swiper로 관리하고 동기화하는 방식은 사용자 경험을 크게 향상시키는 효과적인 방법이다.
이미지가 많이 사용되는 현대 웹 애플리케이션에서 이러한 최적화는 사용자 만족도를 높이고 웹사이트의 품질을 향상시키는 중요한 요소가 된다.