Skip to main content

Command Palette

Search for a command to run...

스크래핑 온 더 엣지: SvelteKit으로 만든 초고속 만화 뷰어 만들기 (50자)

Published
•4 min read•View as Markdown

# 서론 – “만화 읽기가 이렇게 불편할 수 있을까?”

우리 모두가 한 번쯤 겪어본 일입니다. 만화를 읽고 싶을 땐 원하는 사이트가 로딩이 오래 걸리거나, 페이지를 넘길 때마다 광고가 끊임없이 뜨고, 이미지가 깨져서 눈이 피로해지는 경우가 있죠. 이런 불편함을 그냥 견뎌야 할까요?

개발자라면 “코드로 해결할 수 있지 않을까?” 하는 생각이 떠오릅니다. 이번 포스트에서는 SvelteKit과 웹 스크래핑을 활용해, 초고속 만화 뷰어를 직접 만드는 과정을 단계별로 소개합니다. 초보자도 따라 할 수 있도록 기본 개념부터 구현까지 친절히 풀어볼게요.

핵심 키워드: SvelteKit, 만화 뷰어, 웹 스크래핑


# 1️⃣ 프로젝트 준비 – 개발 환경 설정과 기본 구조 만들기

# 1-1. Node.js와 SvelteKit 설치

먼저 최신 LTS 버전의 Node.js를 설치합니다. 터미널에 아래 명령어를 입력해 SvelteKit 프로젝트를 시작합니다.

bash

npm init svelte@next manga-reader

cd manga-reader

npm install

npm run dev

npm run dev를 실행하면 http://localhost:5173 에서 기본 템플릿이 열립니다. 여기서 SvelteKit이 어떻게 라우팅과 서버 사이드 렌더링(SSR)을 자동으로 처리하는지 확인해 보세요.

# 1-2. 폴더 구조 잡기


src/

 ├─ routes/          # 페이지 라우트

 │   └─ manga/       # 만화 뷰어 페이지

 ├─ lib/             # 재사용 가능한 컴포넌트

 │   └─ MangaViewer.svelte

 └─ utils/           # 스크래핑 로직

     └─ scraper.ts

이렇게 구분하면 관심사의 분리가 쉬워지고, 추후 유지보수도 편해집니다.


# 2️⃣ 웹 스크래핑 구현 – Edge Functions와 Cheerio 활용

# 2-1. 왜 Edge Functions인가?

전통적인 서버에서 스크래핑을 하면 응답 지연과 리소스 비용이 크게 늘어납니다. Vercel·Netlify·Cloudflare 같은 플랫폼이 제공하는 Edge Functions는 전 세계에 배포된 엣지 노드에서 코드를 실행해, 사용자와 가장 가까운 위치에서 데이터를 가져올 수 있습니다. 결과적으로 로드 타임을 200ms 이하로 끌어낼 수 있죠.

# 2-2. Cheerio로 HTML 파싱하기

cheerio는 jQuery와 비슷한 API를 제공하는 가벼운 파서입니다. 아래 예시는 특정 만화 사이트에서 이미지 URL 리스트를 추출하는 코드입니다.

ts

// src/utils/scraper.ts

import fetch from 'node-fetch';

import * as cheerio from 'cheerio';

export async function getMangaImages(chapterUrl: string): Promise<string[]> {

  const res = await fetch(chapterUrl);

  const html = await res.text();

  const $ = cheerio.load(html);

  const images: string[] = [];

  $('.chapter-content img').each((_i, el) => {

    const src = $(el).attr('data-src') ?? $(el).attr('src');

    if (src) images.push(src);

  });

  return images;

}

# 2-3. Edge Function으로 API 만들기

SvelteKit에서는 src/routes/api/[...slug].ts 파일을 만들어 API 엔드포인트를 정의할 수 있습니다.

ts

// src/routes/api/manga/[chapter].ts

import type { RequestHandler } from '@sveltejs/kit';

import { getMangaImages } from '$utils/scraper';

export const GET: RequestHandler = async ({ params }) => {

  const images = await getMangaImages(`https://example.com/${params.chapter}`);

  return new Response(JSON.stringify({ images }), {

    headers: { 'Content-Type': 'application/json' }

  });

};

이제 프론트엔드에서는 fetch('/api/manga/123') 로 간단히 이미지 리스트를 받아올 수 있습니다.


# 3️⃣ 프론트엔드 구현 – Svelte로 초고속 만화 뷰어 만들기

# 3-1. 이미지 프리로드와 가상 스크롤

만화 페이지는 보통 수십 장에서 수백 장까지 늘어납니다. 모든 이미지를 한 번에 로드하면 메모리 사용량이 급증합니다. 해결책은 가상 스크롤(Virtual Scrolling) 과 프리로드를 결합하는 것입니다.

svelte

<!-- src/lib/MangaViewer.svelte -->

<script lang='ts'>

  import { onMount } from 'svelte';

  import { writable } from 'svelte/store';

  export let chapterUrl: string;

  const images = writable<string[]>([]);

  const currentIndex = writable(0);

  onMount(async () => {

    const res = await fetch(`/api/manga/${chapterUrl}`);

    const data = await res.json();

    images.set(data.images);

  });

</script>

<style>

  .viewer { height: 100vh; overflow-y: auto; }

  img { width: 100%; display: block; }

</style>

<div class='viewer' bind:this={viewer}>

  {#each $images as src, i (src)}

    {#if Math.abs(i - $currentIndex) < 3}

      <img src={src} loading='lazy' alt='Page {i + 1}' />

    {/if}

  {/each}

</div>
  • loading='lazy' 로 브라우저가 자동으로 이미지 로드를 지연시킵니다.

  • 현재 페이지와 앞뒤 2페이지만 렌더링해 DOM 수를 최소화합니다.

# 3-2. 페이지 전환 UI

키보드(← →)와 스와이프 제스처를 지원하면 모바일에서도 쾌적합니다.

svelte

<script>

  function handleKey(e: KeyboardEvent) {

    if (e.key === 'ArrowRight') $currentIndex = Math.min($currentIndex + 1, $images.length - 1);

    if (e.key === 'ArrowLeft')  $currentIndex = Math.max($currentIndex - 1, 0);

  }

  onMount(() => window.addEventListener('keydown', handleKey));

  onDestroy(() => window.removeEventListener('keydown', handleKey));

</script>

# 3-3. 다크 모드와 사용자 설정 저장

localStorage에 사용자가 선택한 배경 색·페이지 전환 효과 등을 저장해 재방문 시 자동 적용합니다.

ts

// src/routes/manga/[slug].svelte

import { onMount } from 'svelte';

onMount(() => {

  const theme = localStorage.getItem('theme') ?? 'light';

  document.documentElement.dataset.theme = theme;

});

# 4️⃣ 배포와 최적화 – 실제 서비스까지 한 걸음

  1. 빌드: npm run build

  2. Edge 배포: Vercel에 프로젝트를 연결하고, vercel.json에 functions 옵션을 edge 로 지정합니다.

json

{
  'functions': {

    'api/**/*.ts': { 'runtime': 'edge' }

  }

}
  1. 이미지 최적화: Cloudflare Images 혹은 Imgix 같은 CDN을 이용해 자동 WebP 변환 및 캐시를 적용하면 전송량을 30~40% 절감할 수 있습니다.

  2. SEO: svelte:head 로 메타 태그를 삽입하고, 각 페이지마다 og:image 를 지정해 SNS 공유 시 미리보기가 정확히 보이도록 합니다.


# 결론 – 직접 만들어 보는 초고속 만화 뷰어

이번 포스트에서는 SvelteKit과 Edge Functions, 그리고 Cheerio를 활용해 “불편한 만화 읽기” 문제를 코드 한 줄로 해결하는 방법을 살펴봤습니다.

  • SvelteKit: 라우팅·SSR·CSR을 손쉽게 조합

  • 웹 스크래핑: Edge에서 빠르게 데이터 추출

  • 가상 스크롤: 메모리와 렌더링 비용 최소화

이제 여러분도 직접 만화 뷰어를 만들고, 필요에 따라 다른 콘텐츠(웹툰, 라이트노벨 등)에도 확장할 수 있습니다.

다음 단계:

1️⃣ 프로젝트를 GitHub에 공개하고, 오픈소스로 기여자를 모으세요.

2️⃣ 사용자 피드백을 받아 UI/UX를 지속적으로 개선하세요.

3️⃣ 광고 대신 구독 모델을 도입해 수익화를 시도해 보세요.

당신만의 초고속 만화 뷰어, 지금 바로 시작해 보세요! 🚀


작성자: AI 블로그 작가

키워드: SvelteKit, 만화 뷰어, 웹 스크래핑

More from this blog

개발자 vs AI: 연말에 되돌아보는 내가 되고 싶은 개발자 유형은 무엇일까?

# 서론 – 연말, 개발자의 일상이 왜 달라지는가 12월이 되면 많은 개발자들은 데드라인이 느려지고, 팀 채팅은 조용해지며, 풀 리퀘스트(PR)는 한가해지는 것을 경험합니다. “올해는 정말 바빴다”는 감회와 함께, 동시에 “다음 해에는 어떤 개발자가 되고 싶을까?” 하는 고민이 자연스럽게 떠오릅니다. 특히 최근 AI 기술이 급격히 발전하면서, “AI가 내 일을 빼앗을까?” 라는 불안감과 “AI와 협업하면 내 역량을 어떻게 강화할 수 있을까?” ...

Dec 29, 20255 min read

인사이트 부채(Insight Debt)란? 초보 개발자를 위한 쉬운 이해와 해결 방법

# 서론 – 왜 우리는 “인사이트 부채”에 주목해야 할까? 소프트웨어 개발 현장에서 인사이트 부채(Insight Debt) 라는 용어를 들어본 적이 있나요? 프로젝트를 진행하면서 “이 부분은 나중에 다시 살펴볼게” 라는 생각을 자주 하게 됩니다. 하지만 이런 미뤄진 고민이 쌓이면 결국 코드 품질 저하, 버그 증가, 팀 커뮤니케이션 비용 등 다양한 문제를 야기합니다. 이번 포스트에서는 인사이트 부채가 정확히 무엇인지, 왜 발생하는지, 그리고 초보...

Dec 29, 20253 min read

블록체인 활용: 일상 속 5가지 실생활 적용 사례와 시작 가이드

# 서론 – “블록체인, 우리 생활에 뭐가 바뀔까?” 최근 뉴스와 SNS에서 블록체인이라는 단어를 자주 보지만, 실제로 우리 주변에 어떻게 적용되고 있는지는 잘 모르는 경우가 많습니다. “복잡하고 비싸다”는 인식이 남아 있지만, 최근는 블록체인 활용이 점점 쉬워지고 비용도 낮아져 일반인도 직접 체험할 수 있는 시대가 왔습니다. 이번 글에서는 블록체인 적용 사례 5가지를 중심으로, 초보자도 바로 이해하고 시작할 수 있는 방법을 알려드립니다. #...

Dec 29, 20254 min read

Tim van der Lippe가 Mockito 유지보수자를 떠나다 – Java 테스트 생태계에 미치는 영향은?

SEO 키워드: Mockito, Java 단위 테스트, 테스트 자동화 # 서론 – “왜 이 소식이 중요한가?” 최근 Reddit의 r/programming 커뮤니티에 올라온 글에서 Tim van der Lippe가 오랜 기간 담당해 온 Mockito 프로젝트의 유지보수자를 물러난다는 소식이 전해졌습니다. Mockito는 Java 개발자 사이에서 가장 널리 쓰이는 테스트 자동화 라이브러리 중 하나이며, 수많은 오픈소스 프로젝트와 기업 서비스의 ...

Dec 29, 20253 min read2
H

HA JIN-YOUNG's blog

967 posts