UX 디자인

사용자 경험을 높이는 로딩 애니메이션 구현하기

기다림의 시간을 기대감으로 바꾸는 마법

📅 2026.02.15 ⏱️ 9분 읽기 👨‍💻 개발자

💭 왜 로딩 페이지가 필요했나

검사를 마치고 "결과 확인하기" 버튼을 누르면 바로 결과 페이지로 넘어갔습니다. 기술적으로는 문제없지만, 뭔가 허전한 느낌이 들었습니다. "이렇게 바로?" 하는 생각이 들더군요.

그래서 중간에 **분석 중 페이지**를 추가하기로 했습니다. 실제로 복잡한 계산을 하는 건 아니지만, 사용자에게 "AI가 정밀하게 분석하고 있습니다" 같은 느낌을 주고 싶었거든요. 심리학적으로도 약간의 기다림이 결과에 대한 기대감을 높인다고 하더군요.

💡 로딩 페이지의 효과

  • • 기대감 증폭 (결과가 더 특별하게 느껴짐)
  • • 프로페셔널한 느낌 제공
  • • 전면 광고 배치 가능 (수익화)
  • • 결과 로딩 시간 은폐 (실제 있다면)

🎯 디자인 컨셉

로딩 페이지에 담고 싶었던 요소들:

  • 1. 회전하는 스피너 - 뭔가 작동하고 있다는 시각적 피드백
  • 2. 단계별 메시지 - "E/I 성향 분석 중..." 같은 구체적인 정보
  • 3. 진행률 바 - 얼마나 남았는지 시각적으로 표시
  • 4. 전면 광고 영역 - 수익화를 위한 공간

💻 구현 과정

1단계: HTML 구조 잡기

<div class="bg-white rounded-3xl shadow-2xl overflow-hidden">
    <!-- 헤더 -->
    <div class="bg-gradient-to-r from-purple-600 to-indigo-600 text-white px-8 py-12 text-center">
        <div class="text-6xl mb-4">🧬</div>
        <h1 class="text-4xl font-bold mb-4">AI 분석 중...</h1>
        <p>당신의 성격 유형을 정밀 분석하고 있습니다</p>
    </div>
    
    <!-- 광고 영역 -->
    <div class="px-8 py-8 bg-gray-50">
        <div class="adsense-container min-h-[280px]">
            <!-- Google AdSense 코드 -->
        </div>
    </div>
    
    <!-- 진행 상황 -->
    <div class="px-8 py-10 text-center">
        <div class="spinner"></div>
        <p id="statusText">응답 데이터를 처리하고 있습니다...</p>
        <div class="progress-bar">
            <div id="progressBar" style="width: 0%"></div>
        </div>
    </div>
</div>

2단계: 스피너 애니메이션

CSS로 회전하는 스피너를 만들었습니다.

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.spinner {
    animation: spin 1s linear infinite;
    width: 64px;
    height: 64px;
    border: 4px solid rgba(139, 92, 246, 0.2);
    border-top: 4px solid rgb(139, 92, 246);
    border-radius: 50%;
    margin: 0 auto 24px;
}

💡 애니메이션 속도 선택

1초 (1s)로 설정했습니다. 너무 빠르면 어지럽고, 너무 느리면 답답해 보입니다. 여러 번 테스트해본 결과 1초가 가장 자연스러웠습니다.

3단계: 단계별 메시지 표시

MBTI의 경우 7단계 메시지를 준비했습니다.

const messages = [
    '응답 데이터를 처리하고 있습니다...',
    'E/I 성향을 분석하고 있습니다...',
    'S/N 성향을 분석하고 있습니다...',
    'T/F 성향을 분석하고 있습니다...',
    'J/P 성향을 분석하고 있습니다...',
    '16가지 유형 중 매칭 중...',
    '상세 결과를 준비하고 있습니다...'
];

let currentMessageIndex = 0;

function updateMessage() {
    if (currentMessageIndex < messages.length) {
        document.getElementById('statusText').textContent = 
            messages[currentMessageIndex];
        currentMessageIndex++;
    }
}

4단계: 진행률 바 업데이트

let progress = 0;

function updateProgress() {
    if (progress < 100) {
        progress += 14.3;  // 7단계 = 약 14.3%씩
        document.getElementById('progressBar').style.width = 
            Math.min(progress, 100) + '%';
    }
}

// 600ms마다 업데이트 (총 약 4.2초)
const interval = setInterval(() => {
    updateMessage();
    updateProgress();
    
    if (currentMessageIndex >= messages.length) {
        clearInterval(interval);
        setTimeout(goToResult, 800);  // 0.8초 후 결과 페이지로
    }
}, 600);

⏱️ 타이밍 조절의 중요성

처음에는 3초로 설정했는데 너무 짧다는 느낌이 들었습니다. 광고를 볼 시간도 없고, 기대감도 부족했죠. 4~5초가 적당했습니다.

  • • 너무 짧으면 (< 2초): 급한 느낌, 광고 노출 부족
  • • 적당한 길이 (4~5초): 기대감 상승, 광고 인지
  • • 너무 길면 (> 8초): 사용자 이탈

5단계: 결과 페이지로 자동 이동

function goToResult() {
    const mbtiType = localStorage.getItem('mbti_result_type');
    if (mbtiType) {
        window.location.href = \`./result.html?type=\${mbtiType}\`;
    } else {
        alert('결과 데이터를 찾을 수 없습니다.');
        window.location.href = './index.html';
    }
}

🎨 시각적 완성도 높이기

🌈 그라데이션 배경

각 테스트마다 고유한 색상 조합

/* MBTI */
from-purple-600 to-indigo-600

/* 번아웃 */
from-orange-500 to-red-500

✨ Pulse 애니메이션

메시지 텍스트에 부드러운 깜빡임 효과

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.pulse {
    animation: pulse 2s ease-in-out infinite;
}

📱 반응형 디자인

모바일에서도 광고가 제대로 보이도록 최소 높이 설정

min-h-[280px]  /* 모바일 광고 표준 */

📈 수익화 전략

로딩 페이지는 단순한 UX 개선이 아니라 **수익화 전략**의 핵심이었습니다.

광고 배치 전략

전면 광고: 배너 광고보다 높은 CPM
강제 노출: 사용자가 기다리는 동안 자연스럽게 보게 됨
높은 가시성: 화면 중앙에 큰 크기로 배치
방해하지 않음: 어차피 기다려야 하는 시간 활용

⚠️ 주의할 점

절대 8초 이상은 안 됨

아무리 광고 수익이 중요해도 8초 넘으면 사용자가 이탈합니다. 4~5초가 최적입니다.

뒤로가기 버튼 대비

사용자가 뒤로가기를 누르면 검사를 다시 해야 하는 문제가 있었습니다. LocalStorage에 결과를 미리 저장해서 해결했습니다.

광고 로딩 시간 고려

광고가 로드되기 전에 페이지가 넘어가면 광고 수익이 없습니다. 최소 3초는 보장해야 합니다.

🎓 배운 점

  • 1️⃣ 기다림도 경험의 일부: 잘 디자인된 로딩은 오히려 만족도를 높입니다
  • 2️⃣ 수익화와 UX의 균형: 광고를 보여주면서도 사용자가 불편하지 않게
  • 3️⃣ 진행 상황 표시: 사용자는 "얼마나 남았는지" 아는 것만으로도 안심합니다
  • 4️⃣ 타이밍이 생명: 0.5초 차이가 체감에 큰 영향을 줍니다

💡 마치며

로딩 페이지를 만들면서 "사용자 경험"이란 게 단순히 빠르게 만드는 것만이 아니라는 걸 배웠습니다. 때로는 의도적인 지연이 오히려 더 나은 경험을 만들 수 있더군요. 물론 그 시간을 광고로 수익화할 수 있다는 것도 큰 장점이었지만요.

다음에는 스켈레톤 스크린(Skeleton Screen)도 도입해보고 싶습니다. 결과 페이지가 로딩되는 동안 회색 박스로 레이아웃을 미리 보여주는 거죠. 더 세련된 느낌을 줄 수 있을 것 같아요.

🎉

시리즈 완료!

사용자 개인화, 이미지 공유, 데이터 시각화, 로딩 애니메이션까지
모든 핵심 기능 개발 과정을 공유했습니다 ✨

블로그 목록으로 홈으로 가기