SvelteKit으로 만든 초고속 만화 뷰어: 웹 스크래핑부터 배포까지 완전 가이드
# 서론 – “만화 읽을 때마다 느끼는 불편함”
온라인에서 만화를 감상할 때, 페이지 전환이 느리거나 광고가 끊임없이 나타나는 경험, 한 번쯤은 해보셨을 겁니다. 특히 모바일 환경에서는 로딩 시간 하나가 독서 흐름을 깨뜨리는 큰 요인이 되죠. 이런 일상적인 불편을 해결하고 싶어 “코드로 내 손에 맞는 만화 뷰어를 만들 수 있지 않을까?” 하는 생각이 떠오릅니다.
이번 포스트에서는 SvelteKit을 활용해 초고속 만화 뷰어를 직접 구현하는 과정을 단계별로 풀어보겠습니다. 웹 스크래핑, 이미지 최적화, 배포까지 초보자도 따라 할 수 있도록 상세히 설명합니다.
핵심 SEO 키워드:
SvelteKit,만화 뷰어,웹 스크래핑
# 1️⃣ 프로젝트 개요와 목표
| 목표 | 내용 |
|------|------|
| 빠른 로딩 | 이미지 프리로드와 CDN 캐시 활용 |
| 광고 차단 | 불필요한 스크립트와 요소를 제거 |
| 반응형 UI | 모바일·데스크톱 모두 최적화 |
| 쉽게 확장 | 새로운 만화 사이트 추가 시 최소 수정 |
프로젝트는 크게 세 부분으로 나뉩니다.
프론트엔드 – SvelteKit으로 UI와 라우팅 구현
백엔드(Edge Function) – 웹 스크래핑을 통해 원본 이미지 URL을 추출
배포 – Vercel·Netlify 등 서버리스 플랫폼에 배포
# 2️⃣ SvelteKit 기본 설정 (초보자도 OK)
- 프로젝트 생성
bash
npm init svelte@next manga-reader
cd manga-reader
npm install
- 파일 구조
src/
├─ routes/
│ └─ +page.svelte # 메인 뷰 페이지
└─ lib/
└─ api/
└─ fetchManga.ts # Edge Function 호출 함수
- 라우팅 –
src/routes/+page.svelte에 간단한 입력 폼을 만든 뒤, 사용자가 입력한 만화 URL을fetchManga함수에 전달합니다.
svelte
<script lang='ts'>
import { fetchManga } from '$lib/api/fetchManga';
let mangaUrl = '';
let images: string[] = [];
async function loadManga() {
images = await fetchManga(mangaUrl);
}
</script>
<input bind:value={mangaUrl} placeholder='만화 페이지 URL 입력' />
<button on:click={loadManga}>읽기</button>
{#if images.length}
<div class='gallery'>
{#each images as src}
<img src={src} loading='lazy' />
{/each}
</div>
{/if}
SvelteKit은 SSR(Server‑Side Rendering)과 CSR(Client‑Side Rendering)를 자동으로 최적화해 주기 때문에 별도 설정 없이도 빠른 초기 로딩을 경험할 수 있습니다.
# 3️⃣ 웹 스크래핑 구현 – Edge Function에서 이미지 URL 추출
# 3.1 왜 Edge Function인가?
지연 시간 최소화: 사용자와 가장 가까운 엣지 서버에서 실행 → API 호출 횟수 감소
서버 비용 절감: 사용량 기반 과금, 무한히 확장 가능
# 3.2 구현 코드 (Node.js + Cheerio)
src/lib/api/fetchManga.ts
ts
import { json } from '@sveltejs/kit';
import cheerio from 'cheerio';
export async function GET({ url }) {
const target = url.searchParams.get('url');
const res = await fetch(target);
const html = await res.text();
const $ = cheerio.load(html);
// 사이트마다 다르지만 보통 이미지가 <img class='page'> 형태
const imgUrls = $('img.page')
.map((_, el) => $(el).attr('src'))
.get()
.filter(Boolean);
return json({ images: imgUrls });
}
위 코드는 Vercel Edge Functions 혹은 Netlify Functions에 그대로 배포할 수 있습니다.
# 3.3 CORS와 보안
fetch시mode: 'no-cors'대신 서버 측에서 직접 요청 → 브라우저 CORS 문제 회피외부 도메인에 대한 무분별한 요청을 방지하기 위해 허용 도메인 화이트리스트를 설정합니다.
# 4️⃣ 이미지 최적화와 캐시 전략
이미지 포맷 변환 –
sharp라이브러리로 WebP 변환 후 반환 (Edge Function 안에서 처리 가능)CDN 캐시 – Vercel/Netlify가 제공하는 자동 캐시 헤더(
Cache-Control: public, max-age=31536000) 활용Lazy Loading –
<img loading='lazy'>속성으로 화면에 보일 때만 로드
팁: 이미지가 많을 경우
IntersectionObserver를 직접 구현하면 더욱 세밀한 로딩 제어가 가능합니다.
# 5️⃣ 배포와 성능 테스트
| 단계 | 작업 내용 |
|------|-----------|
| 빌드 | npm run build (SvelteKit이 정적 파일과 서버less 함수 생성) |
| 배포 | Vercel CLI vercel --prod 혹은 Netlify UI에 연결 |
| 테스트 | Lighthouse(Chrome DevTools)로 Performance 점수 90점 이상 목표 |
| 모니터링 | Vercel Analytics → 페이지 뷰, 응답 시간 확인 |
배포 후 실제 모바일 기기에서 네트워크·CPU throttling을 적용해 테스트하면, 페이지 최초 로딩이 1~2초 내에 완료되는 것을 확인할 수 있습니다.
# 결론 – 직접 만들고 공유해 보세요!
SvelteKit과 Edge Function을 조합하면, 복잡한 서버 구축 없이도 초고속 만화 뷰어를 손쉽게 구현할 수 있습니다. 웹 스크래핑을 통해 원하는 콘텐츠를 직접 가져오고, 이미지 최적화와 CDN 캐시로 사용자 경험을 크게 향상시킬 수 있죠.
지금 바로 위 과정을 따라해 보시고, 자신만의 커스텀 만화 뷰어를 만들면서 프론트엔드·백엔드 통합 개발 역량을 한 단계 끌어올려 보세요.
행동 유도: 프로젝트를 직접 깃허브에 올리고, 블로그에 사용 후기와 개선 아이디어를 공유해 주세요! 여러분의 피드백이 다음 업데이트를 만드는 원동력이 됩니다. 🚀