Week 5 - Final

High-End UX & Control

프로덕트 완성도 높이기 + 최종 서비스 발표

데모데이

5주간 만든 AI Agent 서비스를 발표하고 피드백을 받습니다

학습 목표

최신 UI/UX

Tailwind CSS와 Framer Motion으로 세련된 인터페이스를 구현합니다.

성능 최적화

Core Web Vitals를 개선하고 로딩 속도를 최적화합니다.

에러 처리

Error Boundary와 폴백 UI로 안정적인 서비스를 만듭니다.

포트폴리오

완성된 프로젝트를 정리하고 발표 자료를 준비합니다.

Part 1: UI/UX 개선

Framer Motion 애니메이션

import { motion } from 'framer-motion';

// 페이드 인 애니메이션
<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.5 }}
>
  <h1>Welcome to My App</h1>
</motion.div>

// 리스트 아이템 순차 등장
const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: { staggerChildren: 0.1 }
  }
};

const item = {
  hidden: { opacity: 0, x: -20 },
  show: { opacity: 1, x: 0 }
};

<motion.ul variants={container} initial="hidden" animate="show">
  {items.map(i => (
    <motion.li key={i} variants={item}>{i}</motion.li>
  ))}
</motion.ul>

로딩 스켈레톤

// Tailwind CSS로 스켈레톤 UI
function LoadingSkeleton() {
  return (
    <div className="animate-pulse">
      <div className="h-4 bg-gray-200 rounded w-3/4 mb-4"></div>
      <div className="h-4 bg-gray-200 rounded w-1/2 mb-4"></div>
      <div className="h-32 bg-gray-200 rounded mb-4"></div>
      <div className="h-4 bg-gray-200 rounded w-full"></div>
    </div>
  );
}

// 사용 예시
function DiaryList() {
  const { data, isLoading } = useDiaries();

  if (isLoading) return <LoadingSkeleton />;

  return <DiaryCards data={data} />;
}

Part 2: 성능 최적화

Core Web Vitals 체크리스트

LCP (Largest Contentful Paint) < 2.5s

이미지 최적화, 폰트 프리로드, 서버 응답 시간 개선

FID (First Input Delay) < 100ms

JavaScript 번들 크기 줄이기, 코드 스플리팅

CLS (Cumulative Layout Shift) < 0.1

이미지 크기 명시, 폰트 로딩 최적화

Next.js 이미지 최적화

import Image from 'next/image';

// 자동 최적화 + lazy loading
<Image
  src="/hero.jpg"
  alt="Hero image"
  width={1200}
  height={600}
  priority // LCP 이미지는 priority 추가
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

// 반응형 이미지
<Image
  src="/photo.jpg"
  alt="Photo"
  fill
  sizes="(max-width: 768px) 100vw, 50vw"
  style={{ objectFit: 'cover' }}
/>

코드 스플리팅

import dynamic from 'next/dynamic';

// 무거운 컴포넌트는 동적 임포트
const Chart = dynamic(() => import('./Chart'), {
  loading: () => <LoadingSkeleton />,
  ssr: false, // 클라이언트에서만 렌더링
});

// 사용
function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Chart data={chartData} />
    </div>
  );
}

Part 3: 에러 처리

Error Boundary 구현

'use client';

import { ErrorBoundary } from 'react-error-boundary';

function ErrorFallback({ error, resetErrorBoundary }) {
  return (
    <div className="p-8 text-center">
      <h2 className="text-xl font-bold text-red-600 mb-4">
        문제가 발생했습니다
      </h2>
      <p className="text-gray-600 mb-4">{error.message}</p>
      <button
        onClick={resetErrorBoundary}
        className="px-4 py-2 bg-blue-600 text-white rounded"
      >
        다시 시도
      </button>
    </div>
  );
}

// 사용
<ErrorBoundary
  FallbackComponent={ErrorFallback}
  onReset={() => {
    // 상태 초기화 로직
  }}
>
  <MyComponent />
</ErrorBoundary>

API 에러 처리

// 재시도 로직이 포함된 fetch wrapper
async function fetchWithRetry(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url, options);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      return await response.json();
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(r => setTimeout(r, 1000 * (i + 1))); // 점진적 대기
    }
  }
}

// 사용자 친화적 에러 메시지
function getErrorMessage(error) {
  if (error.message.includes('network')) {
    return '인터넷 연결을 확인해주세요.';
  }
  if (error.message.includes('401')) {
    return '로그인이 필요합니다.';
  }
  return '잠시 후 다시 시도해주세요.';
}

Part 4: 발표 준비

발표 구조 (5분)

  1. 문제 정의 (30초) - 왜 이 서비스를 만들었는가?
  2. 솔루션 소개 (1분) - 어떻게 해결했는가?
  3. 라이브 데모 (2분) - 실제 동작 시연
  4. 기술 스택 (1분) - 어떤 기술을 사용했는가?
  5. 향후 계획 (30초) - 다음 단계는?

데모 체크리스트

  • 인터넷 연결 백업 준비 (핫스팟)
  • 데모 시나리오 미리 연습
  • 에러 발생 시 대처 방안 준비
  • 녹화된 영상 백업 (만약을 위해)
  • QR 코드로 실시간 접속 유도
발표 팁: 기술적 세부사항보다 "사용자에게 주는 가치"를 강조하세요. 청중이 "나도 써보고 싶다"고 느끼게 만드는 것이 목표입니다.

과정 완료 후 다음 단계

운영 & 모니터링

Firebase Analytics, 에러 트래킹, 비용 모니터링으로 서비스를 안정적으로 운영합니다.

Multi-Agent 시스템

여러 AI Agent가 협력하는 복잡한 워크플로우를 설계합니다.

커뮤니티

수강생 네트워크를 통해 지속적으로 학습하고 협업합니다.

오픈소스 기여

만든 Agent를 오픈소스로 공개하고 커뮤니티에 기여합니다.

축하합니다!

5주간의 과정을 완료했습니다! 이제 여러분은:

  • AI Agent의 개념과 아키텍처를 이해합니다
  • Replit, Firebase, Claude Code 등 개발 도구를 활용할 수 있습니다
  • Claude, Gemini, ElevenLabs 등 AI API를 연동할 수 있습니다
  • 자동화된 워크플로우를 설계하고 구현할 수 있습니다
  • 실제 운영 가능한 AI Agent를 배포할 수 있습니다
← 4주차로과정 홈으로 →