이번 주말에 Website Tracker를 만들었습니다 — 배운 점

발행: (2026년 1월 1일 오전 03:37 GMT+9)
8 min read
원문: Dev.to

I’m happy to translate the article for you, but I don’t see any text to translate beyond the source line you provided. Could you please paste the content you’d like translated (or the specific sections you want translated) here? Once I have the text, I’ll keep the source link at the top and translate the rest into Korean while preserving the original formatting.

문제

  • 내가 가장 많이 방문하는 사이트를 추적
  • 실시간으로 사이트 상태(업/다운) 모니터링
  • 프로젝트/클라이언트별로 사이트 정리
  • 사용 패턴 및 분석 표시
  • 모든 것을 로컬에 보관(클라우드, 계정 없음)

The Solution: SiteOps

SiteOps는 vanilla JavaScript 로 작성된 웹 앱으로, 브라우저에서만 실행됩니다. 모든 데이터는 localStorage에 저장되며, 백엔드, 데이터베이스, 계정이 필요 없습니다.

  • Live Demo:
  • Source Code:

Tech Stack

  • Vanilla HTML / CSS / JavaScript – 프레임워크 없이, 빌드 과정 없이
  • Chart.js – 분석 시각화
  • localStorage – 클라이언트 측 데이터 영구 저장
  • PWA‑ready – 웹 앱으로 설치 가능

주요 기능

1. 실시간 상태 모니터링

각 웹사이트 카드가 시각적 표시와 함께 실시간 상태(온라인/오프라인)를 보여줍니다.

async function checkWebsiteStatus(url) {
    try {
        const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(url)}`;
        const response = await fetch(proxyUrl, {
            method: 'GET',
            signal: controller.signal
        });
        return response.ok ? 'online' : 'offline';
    } catch (error) {
        return 'offline';
    }
}

2. 방문 추적 및 분석

모든 방문을 타임스탬프, 디바이스 유형 및 패턴과 함께 추적합니다.

function visitWebsite(url) {
    const website = this.websites.find(w => w.url === url);
    if (website) {
        website.visits = (website.visits || 0) + 1;
        website.lastVisited = new Date().toISOString();

        // Track device type
        website.visitHistory.push({
            timestamp: new Date().toISOString(),
            deviceType: this.getDeviceType(),
            hour: new Date().getHours()
        });

        this.saveWebsites();
    }
    window.open(url, '_blank');
}

3. 종합 분석 대시보드

Chart.js를 사용해 시각화합니다:

  • 30일간 방문 추세
  • 카테고리별 분류
  • 디바이스 사용량(데스크톱 / 모바일 / 태블릿)
  • 가장 많이 방문한 웹사이트
  • 사용량이 가장 높은 시간대 및 요일

4. 로컬 우선 아키텍처

모든 데이터가 localStorage에 저장됩니다.

function saveWebsites() {
    localStorage.setItem('websiteTracker', JSON.stringify(this.websites));
}

function loadWebsites() {
    const stored = localStorage.getItem('websiteTracker');
    return stored ? JSON.parse(stored) : [];
}

도전 과제 및 학습

도전 과제 1: 상태 확인을 위한 CORS

문제: 직접 fetch가 CORS에 의해 차단됩니다.
해결책: allorigins.win 프록시를 사용합니다.

const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(url)}`;

학습: 브라우저 보안은 정당한 이유로 엄격합니다; 클라이언트 측 모니터링에는 우회 방법이 필요합니다.

도전 과제 2: 프레임워크 없이 반응형 디자인

문제: 순수 CSS만으로 복잡하고 반응형 대시보드를 구축하는 것.
해결책: repeat(auto-fit, minmax())를 활용한 CSS Grid.

.websites-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 20px;
}

학습: 최신 CSS Grid는 프레임워크 없이 대부분의 레이아웃을 처리합니다.

도전 과제 3: 데이터 영속성

문제: 브라우저 재시작 후에도 데이터가 유지되도록 보장하는 것.
해결책: 모든 작업 후 localStorage에 저장하고 백업을 위해 내보내기/가져오기를 제공합니다.

학습: localStorage는 신뢰할 수 있지만 용량이 제한적입니다(~5‑10 MB). 더 큰 데이터셋은 IndexedDB가 더 적합합니다.

도전 과제 4: 실시간 UI 업데이트

문제: 페이지 새로고침 없이 UI를 업데이트하는 것.
해결책: 수동 DOM 업데이트를 통한 이벤트 기반 아키텍처.

function renderWebsites() {
    const filtered = this.getFilteredWebsites();
    grid.innerHTML = filtered.map(website => this.createWebsiteCard(website)).join('');
}

학습: 바닐라 JS도 복잡한 UI를 처리할 수 있지만, 앱이 커질수록 상태 관리가 어려워집니다.

디자인 결정

왜 바닐라 JavaScript인가?

  • 단순성: 빌드 프로세스 없이, 의존성 없음
  • 성능: 빠른 로드 시간, 최소 번들 크기
  • 학습: 기본 개념에 대한 이해를 심화
  • 이식성: HTML/CSS/JS가 동작하는 어디서든 작동

왜 localStorage인가?

  • 프라이버시: 데이터가 브라우저를 떠나지 않음
  • 단순성: 백엔드 인프라 필요 없음
  • 속도: 즉시 저장/로드
  • 오프라인: 최초 로드 후 인터넷 없이 작동

왜 Chart.js인가?

  • 쉬운 통합: CDN, 빌드 단계 없음
  • 우수한 기본값: 바로 사용할 수 있는 전문적인 외관
  • 유연성: 필요 시 맞춤 설정 가능

특별한 기능

  • 5‑스타 평점 시스템 – 빠른 참고를 위해 웹사이트를 평가합니다
  • 키보드 단축키 – 파워 유저 친화적 (Ctrl + N, Ctrl + F 등)
  • 내보내기 / 가져오기 – 데이터를 JSON 형식으로 백업합니다
  • 디바이스 추적 – 데스크톱 / 모바일 / 태블릿 사용 통계
  • 재방문 비율 – 재방문에 대한 분석 제공
  • 글래스모피즘 UI – 현대적이고 깔끔한 디자인

내가 다르게 할 것

  • IndexedDB – 더 큰 데이터셋과 향상된 성능을 위해
  • Service Worker – 진정한 오프라인 기능 및 캐싱
  • WebSockets – 상태 모니터링을 위한 실시간 푸시 업데이트

실시간 상태 업데이트 (백엔드를 추가한 경우)

  • Testing – 핵심 기능에 대한 단위 테스트 추가
  • TypeScript – 코드 유지 보수성을 향상시키기 위해

직접 사용해 보기

live demo를 방문하고:

  • 몇 개의 웹사이트를 추가하세요
  • 몇 번 방문하세요
  • 분석 대시보드를 확인하세요
  • 데이터를 내보내세요

모든 데이터는 브라우저에만 저장됩니다 — 완전히 개인적이며 로컬에 보관됩니다.

오픈 소스

SiteOps는 오픈 소스이며 GitHub에서 이용할 수 있습니다. 기여를 환영합니다!

최종 생각

SiteOps를 만들면서 배운 점:

  • Vanilla JS로 복잡한 앱을 만들 수 있다
  • localStorage는 로컬‑퍼스트 앱에 강력하다
  • 좋은 UX가 프레임워크보다 더 중요하다
  • 때때로 최고의 해결책은 가장 단순한 것이다

여러 웹사이트를 추적하고 있다면 SiteOps를 사용해 보세요. 피드백이나 제안이 있으면 언제든 알려 주세요!

Tags: #javascript #webdev #productivity #opensource #pwa #localstorage #analytics #webdevelopment

Back to Blog

관련 글

더 보기 »