청소클라쓰
전주 청소업체 마케팅 홍보용 웹사이트 개발
Problem
고객사인 전주 청소업체 '청소클라쓰' 업체 의뢰를 맡아 진행한 업체 마케팅 홍보용 웹사이트 개발 프로젝트입니다. Next.js ISR 기반 서버 렌더링과 정적 캐싱을 적용하고, Supabase(PostgreSQL + RLS + Auth + Storage)를 BaaS로 활용했습니다. Docker 컨테이너로 패키징하여 AWS LightSail에 배포하며, GitHub Actions + Jenkins를 통한 CI/CD 파이프라인을 구축했습니다. 주요 기능으로는 네이버 블로그 후기 링크 연동 및 바로가기, 견적 문의 폼(Gmail SMTP), 관리자 페이지 CRUD, SEO 구조(robots, sitemap, JSON-LD)가 있습니다.
Stack
- Next.js
- ISR 기반 서버 렌더링, Metadata API, 이미지 최적화(/_next/image + 디스크 캐시)
- React
- 컴포넌트 기반 마케팅 페이지 UI 구성
- Supabase
- PostgreSQL(RLS) + Auth + Storage — BaaS로 백엔드 인프라 비용 최소화
- Gmail SMTP
- Nodemailer 기반 견적 문의 이메일 발송
- GitHub Actions
- CI/CD 파이프라인 자동화
- Docker
- Next.js standalone 모드 컨테이너화 배포
- AWS LightSail
- 경량 VPS 호스팅
Key Contributions
이미지 중심 마케팅 페이지 설계 및 렌더링 최적화
업체 대표 요구사항을 정리하여 UI/UX 방향을 정의하고, 이미지 중심의 마케팅 랜딩 페이지를 설계했습니다. Hero 애니메이션을 CSS @keyframes로 전환하고, 하단 섹션을 next/dynamic으로 분리하여 초기 번들을 경량화했습니다.
Lighthouse Performance 80 → 98점, FCP -58%, LCP -29%
Gmail SMTP 기반 견적 문의 시스템 구현
Nodemailer + Gmail SMTP를 연동하여 고객 견적 문의 폼을 구현했습니다. 서버 액션으로 이메일 발송을 처리하고, 관리자에게 즉시 알림이 가도록 설계했습니다.
견적 문의 10배 증가 달성
SEO 구조 최적화 및 지역 검색 노출 강화
JSON-LD 스키마를 CleaningService + LocalBusiness 복합 타입으로 확장하고, serviceType·areaServed 등 지역 업종 정보를 명시했습니다. sitemap의 lastModified를 DB 최신 updated_at 기반으로 동적 반영하도록 개선했습니다.
블로그 방문자 수 4.3배 증가, 지역 키워드 유입 증가
관리자 페이지 및 CRUD 기능 구현
Supabase RLS 기반 인증과 Storage 연동으로 서비스·후기·설정을 관리하는 어드민 페이지를 구축했습니다. 비개발자인 업체 대표가 직접 콘텐츠를 관리할 수 있도록 UI를 단순화했습니다.
CI/CD 파이프라인 및 컨테이너 배포 구축
GitHub Actions → Jenkins → Docker 빌드 → AWS LightSail 배포까지의 자동화 파이프라인을 구축했습니다. Next.js standalone 모드로 이미지 크기를 최소화했습니다.
Troubleshooting
Core Web Vitals 성능 저하 문제
SNext.js ISR 기반으로 서버 렌더링과 정적 캐싱을 적용했음에도 Lighthouse 측정 결과 Performance 80점, FCP 3,088ms, LCP 4,248ms로 공식 성능 임계값에 미달한 상태였습니다. 렌더 블로킹 리소스 비용이 2,171ms로 측정되어 초기 렌더 지연의 주요 원인이었습니다. 원인을 분석한 결과, 웹폰트를 @import 방식으로 로딩하면서 외부 CDN CSS 요청이 렌더링을 막고 있었고, Hero 영역의 텍스트가 motion.js 의존으로 인해 하이드레이션 이후에야 표시되고 있었습니다. 또한 하단 섹션(Services, BlogReviews, ContactForm)을 직접 import하고 있어 react-slick, motion 등의 라이브러리가 초기 번들에 포함되는 구조였습니다.
A웹폰트의 @import를 제거하고, 서버에서 CDN CSS를 fetch(24시간 캐시)한 뒤 인라인 <style>로 주입해 외부 요청으로 인한 렌더 블로킹을 제거했습니다. Hero 애니메이션은 motion.js 대신 CSS @keyframes로 전환해 초기 렌더 시점에 LCP 텍스트가 바로 노출되도록 했습니다. 하단 섹션은 next/dynamic으로 분리해 폴드 아래 JavaScript를 초기 번들에서 제외하고, 첫 서비스 이미지에만 priority를 부여해 preload를 유도했습니다. 또한 Footer와 MobilePhoneButton의 불필요한 use client를 제거해 서버 컴포넌트로 전환했습니다.
RFCP -58.2% (3,088ms → 1,291ms), LCP -28.7% (4,248ms → 3,029ms), 렌더 블로킹 비용 -94.8% (2,171ms → 112ms). 실서버 Lighthouse 측정 결과, Performance 점수 80점 → 98점. FCP 50% 개선, LCP 49% 개선, 렌더 블로킹 비용 78% 절감.
검색 엔진의 지역 업체 인식 실패 및 콘텐츠 갱신 지연 문제
SISR 적용으로 Lighthouse SEO 점수는 100점이었지만, 실제 "전주 청소업체", "전북 거주청소" 같은 지역+업종 키워드에서 구조화된 결과로 노출되지 않는 문제가 있었습니다. JSON-LD 스키마가 LocalBusiness 단일 타입으로만 설정되어 검색 엔진이 청소 업종으로 정확히 분류하지 못했고, sitemap의 lastModified가 항상 현재 시각으로 찍히는 구조라 관리자가 콘텐츠를 수정해도 변경 시점을 명확히 인식하지 못했습니다.
AJSON-LD 타입을 ["CleaningService", "LocalBusiness"]로 확장하고, serviceType에 거주청소·정기청소·특수청소 등을 명시했습니다. telephone, image, areaServed를 추가해 지역 검색에서의 업체 정보 인식 정확도를 높였습니다. sitemap은 DB의 서비스·후기·설정 테이블의 최신 updated_at을 병렬 조회해 실제 변경 시점을 lastModified에 반영하도록 개선했습니다.
RJSON-LD 세분화와 동적 sitemap 반영 이후 검색 엔진의 비즈니스 정보 인식이 강화되었고, 지역 키워드 기반 유입이 증가했습니다. 블로그 방문자 수 4.3배 증가, 견적 문의 건수 10배 증가.