개요
- Jekyll 기반 GitHub Pages 블로그를 처음부터 설치하고 로컬에서 실행하는 과정을 설명함
사전 준비사항
필수 도구 확인
- 블로그 구축에 필요한 도구들
- Git
- 버전 관리 시스템
- GitHub Pages 배포에 필수
- Ruby
- Jekyll이 동작하는 런타임 환경
- 버전 2.5 이상 권장
- RubyGems
- Ruby 패키지 관리자
- Ruby 설치 시 함께 설치됨
- Bundler
- Ruby 의존성 관리 도구
- Jekyll 프로젝트 관리에 필수
- Git
운영체제별 도구 설치
Windows
- Ruby 설치
- RubyInstaller 다운로드
- RubyInstaller 공식 사이트 접속
- Ruby+Devkit 최신 버전 다운로드
- 설치 과정
- 다운로드한 설치 파일 실행
- “Add Ruby executables to your PATH” 옵션 체크
- MSYS2 설치 단계에서 모든 옵션 선택 (1, 2, 3)
- 설치 확인
1 2
ruby -v gem -v
- RubyInstaller 다운로드
- Git 설치
- Git for Windows 다운로드
- Git 공식 사이트 접속
- 최신 버전 다운로드
- 설치 과정
- 기본 설정으로 설치 진행
- 설치 확인
1
git --version
- Git for Windows 다운로드
- Bundler 설치
1 2 3 4
gem install bundler # 설치 확인 bundle -v
macOS
- Homebrew 설치
- 터미널에서 실행
1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- 설치 확인
1
brew --version
- 터미널에서 실행
- Ruby 설치
- rbenv를 통한 Ruby 설치
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# rbenv 설치 brew install rbenv ruby-build # rbenv 초기화 rbenv init # .zshrc 또는 .bash_profile에 추가 echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc source ~/.zshrc # 설치 가능한 Ruby 버전 확인 rbenv install -l # Ruby 설치 (최신 안정 버전) rbenv install 3.2.2 rbenv global 3.2.2 # 설치 확인 ruby -v
- rbenv를 통한 Ruby 설치
- Git 설치
1 2 3 4 5
# Git 설치 brew install git # 설치 확인 git --version
- Bundler 설치
1 2 3 4
gem install bundler # 설치 확인 bundle -v
Jekyll 테마 선택 및 설치
테마 찾기
- Jekyll 테마 사이트
- Jekyll Themes
- 무료 Jekyll 테마 모음
- 카테고리별 분류
- 미리보기 제공
- Jekyll Themes.io
- 무료/유료 테마 제공
- 인기순, 최신순 정렬
- 상세한 테마 설명
- JamStack Themes - Jekyll
- JamStack 기반 테마 모음
- Jekyll 테마 필터링
- GitHub 스타 수 표시
- GitHub Jekyll Theme 토픽
- GitHub에서 직접 검색
- 최신 업데이트 확인 용이
- 이슈, PR 활동 확인 가능
- Jekyll Themes
인기 Jekyll 테마 소개
- Chirpy
- 깔끔한 디자인의 블로그 테마
- 다크 모드 지원
- 카테고리, 태그, 검색 기능 내장
- GitHub Repository
- Minimal Mistakes
- 가장 많이 사용되는 테마 중 하나
- 반응형 디자인
- 다양한 레이아웃 옵션
- GitHub Repository
- Beautiful Jekyll
- 초보자 친화적인 테마
- 간단한 설정
- 빠른 시작 가능
- GitHub Repository
- TeXt Theme
- 문서화 친화적 테마
- 다국어 지원
- 커스터마이징 용이
- GitHub Repository
- Basically Basic
- 미니멀한 디자인
- 빠른 로딩 속도
- 접근성 중심 설계
- GitHub Repository
GitHub에서 테마 가져오기
- 방법 1, 2 중 선택
- Fork 하기
- GitHub에서 테마 Repository 접속
- 예시: Chirpy 테마
- Fork 버튼 클릭
- Repository name을
username.github.io
형식으로 변경 - username은 자신의 GitHub 사용자명
- Repository name을
생성된 Repository 확인
- 로컬로 Clone
1 2 3 4 5 6 7 8
# 원하는 디렉토리로 이동 cd ~/Documents # Repository Clone git clone https://github.com/username/username.github.io.git # 프로젝트 디렉토리로 이동 cd username.github.io
Template 사용하기
- GitHub에서 “Use this template” 버튼 클릭
- Repository name 입력
username.github.io
형식 권장
- Public으로 설정
- GitHub Pages는 Public Repository에서만 무료
“Create repository from template” 클릭
- 생성된 Repository Clone
1 2
git clone https://github.com/username/username.github.io.git cd username.github.io
Jekyll 블로그 설정
의존성 설치
- Gemfile 확인
- 프로젝트 루트에 있는 Gemfile 열기
- 테마에서 제공하는 기본 Gemfile 사용
- 필요한 gem 패키지 목록 예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
source "https://rubygems.org" gem "jekyll" gem "jekyll-theme-chirpy" # Windows and JRuby does not include zoneinfo files install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do gem "tzinfo" gem "tzinfo-data" end # Performance-booster for watching directories on Windows gem "wdm", :install_if => Gem.win_platform? # Jekyll compatibility with Ruby 3.0 gem "webrick"
- Bundle 설치 실행
1 2
# 의존성 설치 bundle install
- 설치 확인
1 2
# Jekyll 버전 확인 bundle exec jekyll -v
블로그 기본 설정
- _config.yml 파일 수정
- 기본 정보 설정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# 사이트 제목 title: # 사이트 설명 tagline: # 사이트 URL url: "https://username.github.io" # GitHub 사용자명 github: username: username # 소셜 정보 social: name: Your Name email: your.email@example.com links: - https://github.com/username - https://twitter.com/username # 타임존 설정 timezone: Asia/Seoul # 언어 설정 lang: ko-KR
- 테마 설정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 테마 모드 theme_mode: dual # [light | dark | dual] # 아바타 이미지 avatar: /assets/img/profile.jpg # TOC (Table of Contents) 설정 toc: true # 댓글 시스템 설정 comments: active: giscus # [disqus | utterances | giscus] # Giscus 설정 giscus: repo: username/username.github.io repo_id: YOUR_REPO_ID category: Comments category_id: YOUR_CATEGORY_ID # Google Analytics google_analytics: id: G-XXXXXXXXXX
- 기본 정보 설정
프로필 이미지 추가
- 이미지 파일 준비
- 정사각형 이미지 권장
- 추천 크기: 512x512px
- 파일 형식
- PNG, JPG 지원
- 파일 배치
- assets/img 디렉토리에 이미지 파일 복사
- _config.yml의 avatar 경로와 일치하도록 저장
- 정사각형 이미지 권장
로컬에서 블로그 실행하기
Jekyll 개발 서버 시작
- 기본 실행 방법
1 2
# 프로젝트 디렉토리에서 실행 bundle exec jekyll serve
- 자동 새로고침 옵션
1 2 3 4
# LiveReload 기능 활성화 bundle exec jekyll serve --livereload # 브라우저에서 파일 수정 시 자동 새로고침됨
- 포트 변경
1 2
# 다른 포트로 실행 (기본: 4000) bundle exec jekyll serve --port 4001
- 빌드 캐시 초기화
1 2 3
# 기존 빌드 파일 삭제 후 실행 bundle exec jekyll clean bundle exec jekyll serve
브라우저에서 확인
- 로컬 서버 접속
- 주소창에 입력
http://localhost:4000
http://127.0.0.1:4000
- 블로그 메인 페이지 확인
- 메뉴 및 기능 테스트
- 주소창에 입력
- 변경사항 실시간 확인
- 파일 수정 후 저장
- LiveReload 사용 시 자동 새로고침
- 수동 새로고침 필요 시
- Windows:
Ctrl + R
또는F5
- Mac:
Cmd + R
- Windows:
- 브라우저 캐시 강제 새로고침
- Windows:
Ctrl + Shift + R
- Mac:
Cmd + Shift + R
- Windows:
첫 번째 포스트 작성하기
포스트 파일 생성
- 파일 이름 규칙
- 형식
YYYY-MM-DD-title.md
- 예시
2025-10-11-my-first-post.md
- 위치
_posts
디렉토리에 생성
- 형식
- 포스트 파일 생성
- _posts 디렉토리에 새 파일 생성
- 파일명: 2025-10-11-my-first-post.md
- 텍스트 편집기로 열기
- VSCode, 메모장 등 사용
- _posts 디렉토리에 새 파일 생성
Front Matter 작성
- 기본 구조 ```yaml — title: “첫 번째 포스트” author: name: Your Name link: https://github.com/username date: 2025-10-11 14:00:00 +0900 category:
- 주요 옵션 설명
- title
- 포스트 제목
- 따옴표로 감싸기 권장
- date
- 작성 날짜와 시간
- 타임존 포함
- category
- 카테고리 분류
- 배열 형식으로 작성
- 대분류, 소분류 지원
- tags
- 태그 목록
- 배열 형식으로 작성
- pin
- 메인 페이지에 고정
- true/false
- math
- 수학 수식 렌더링 활성화
- true/false
- mermaid
- 다이어그램 렌더링 활성화
- true/false
- title
본문 작성
- Markdown 기본 문법
1 2 3 4 5 6
# 제목 1 ## 제목 2 ### 제목 3 - 일반 텍스트 작성 - 들여쓰기를 통한 계층 구조
- 이미지 삽입
- 이미지 추가 방법
- 이미지 파일을 assets/img 폴더에 저장
- Markdown에서 참조
1

- 이미지 추가 방법
- 코드 블록
- 코드 작성 예시
1 2
def hello_world(): print("Hello, Jekyll!")
- 코드 작성 예시
- 링크 추가
- 외부 링크
GitHub Pages에 배포하기
Git 설정
- Git 사용자 정보 설정
1 2 3 4 5 6
# 전역 설정 git config --global user.name "Your Name" git config --global user.email "your.email@example.com" # 설정 확인 git config --list
- Git 저장소 확인
1 2 3
# 이미 Clone한 경우 이 단계는 건너뜀 # Git 상태 확인 git status
변경사항 커밋
- 작성한 포스트 추가
1 2 3 4 5 6 7 8 9 10 11
# 새 파일 추가 git add _posts/2025-10-11-my-first-post.md # 또는 모든 변경사항 추가 git add . # 상태 확인 git status # 커밋 git commit -m "첫 번째 포스트 작성"
- 설정 파일 변경사항 커밋
1 2 3 4 5
# 설정 파일 추가 git add _config.yml # 커밋 git commit -m "블로그 기본 설정 완료"
GitHub에 푸시
- 원격 저장소 확인
1 2
# 원격 저장소 목록 확인 git remote -v
- 변경사항 푸시
1 2 3 4 5
# main 브랜치에 푸시 git push origin main # 또는 master 브랜치인 경우 git push origin master
GitHub Pages 설정 확인
- GitHub Repository 설정
- GitHub에서 Repository 접속
- Settings 메뉴 클릭
- Pages 섹션으로 이동
- Source 설정 확인
- Branch: main (또는 master)
- Folder: / (root)
- Save 버튼 클릭
- 배포 상태 확인
- Actions 탭에서 빌드 진행 상황 확인
- 녹색 체크 표시가 나타나면 배포 완료
- 배포된 사이트 접속
- 브라우저에서 접속
https://username.github.io
- 포스트 확인
- 기능 테스트
- 브라우저에서 접속
주요 디렉토리 구조 이해하기
Jekyll 프로젝트 구조
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
username.github.io/
├── _config.yml # 사이트 전역 설정
├── _posts/ # 블로그 포스트
│ └── YYYY-MM-DD-title.md
├── _layouts/ # 레이아웃 템플릿
│ ├── default.html
│ └── post.html
├── _includes/ # 재사용 가능한 컴포넌트
│ ├── header.html
│ └── footer.html
├── _sass/ # SASS 스타일시트
│ └── main.scss
├── assets/ # 정적 파일
│ ├── css/
│ ├── js/
│ └── img/
├── _site/ # 생성된 사이트 (Git 무시)
├── .gitignore # Git 무시 파일 목록
├── Gemfile # Ruby 의존성 정의
├── Gemfile.lock # 의존성 버전 고정
└── index.html # 메인 페이지
중요 디렉토리 설명
- _posts
- 역할
- 블로그 포스트 저장 위치
- 파일 규칙
- YYYY-MM-DD-title.md 형식
- 주의사항
- 날짜가 미래인 포스트는 표시되지 않음
- –future 옵션으로 확인 가능
- 역할
- assets
- 역할
- 이미지, CSS, JavaScript 등 정적 파일
- 구조
- img: 이미지 파일
- css: 스타일시트
- js: JavaScript 파일
- 참조 방법
- Markdown:
/assets/img/image.jpg
- HTML:
/assets/img/image.jpg
- Markdown:
- 역할
- _site
- 역할
- Jekyll이 생성한 정적 사이트
- 특징
- 빌드할 때마다 자동 생성
- Git에 커밋하지 않음
- 주의사항
- 직접 수정하지 말 것
- 수정 사항은 소스 파일에서
- 역할
테마 커스터마이징
스타일 수정
- SCSS 파일 위치
_sass
디렉토리assets/css
디렉토리
- 커스텀 스타일 추가
- _sass 디렉토리에 custom.scss 파일 생성
- 색상 변경 예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// _sass/custom.scss // 메인 컬러 변경 $primary-color: #007bff; $secondary-color: #6c757d; // 다크 모드 배경색 $dark-bg: #1a1a1a; // 링크 색상 a { color: $primary-color; &:hover { color: darken($primary-color, 10%); } }
레이아웃 수정
- 레이아웃 파일 확인
_layouts
디렉토리- default.html
- 기본 레이아웃
- post.html
- 포스트 레이아웃
- page.html
- 페이지 레이아웃
커스텀 레이아웃 생성 ```html — layout: default —
Jekyll 블로그 설치 및 로컬 실행 가이드
<!DOCTYPE html>
Jekyll 블로그 이미지 자동 최적화
개요
</h2>- Jekyll 기반 블로그에서 이미지 자동 최적화 시스템을 구축하여 웹 성능을 개선한 과정을 소개함
문제 상황 분석
</h2>초기 성능 문제
</h3>- 기술 블로그에서 측정된 성능 지표
- 이미지 용량
- 149MB
- 페이지 로딩 시간
- 3-5초 (이미지 중심 페이지)
- 이미지 파일 수
- 1,000개 이상
- 이미지 용량
이미지 현황 파악
</h3>1
2
3
4
5
6
7
# 이미지 디렉토리 용량 분석
du -sh assets/img
# 결과: 149M assets/img
# 이미지 파일 개수 확인
find assets/img -type f \( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" \) | wc -l
# 결과: 1,000개 이상의 이미지 파일
- 이미지 파일 특성
- 파일 형식
- PNG, JPEG
- 압축 상태
- 압축되지 않은 원본 파일
- 파일 수
- 1,000개 이상의 이미지 파일
- 파일 형식
Core Web Vitals 측정
</h3>- Core Web Vitals 지표
Google이 정의한 웹사이트 사용자 경험을 측정하는 핵심 지표
- 측정 방법
- 측정 도구
- Chrome DevTools, Lighthouse
- 측정 환경
- 로컬 Jekyll 서버 (localhost:4000)
1 2 3
# Lighthouse CLI를 사용한 성능 측정 npm install -g lighthouse lighthouse http://localhost:4000 --output=json --output-path=./lighthouse-report.json
- 측정 도구
측정된 Core Web Vitals 지표
- LCP (Largest Contentful Paint): 3.2초
- 페이지의 가장 큰 콘텐츠 요소가 화면에 렌더링되는 시간
- 좋은 점수: 2.5초 이하, 개선 필요: 4.0초 초과
이미지가 가장 큰 콘텐츠인 경우 로딩 시간에 직접 영향
- CLS (Cumulative Layout Shift): 0.15
- 페이지 로딩 중 예상치 못한 레이아웃 변화의 정도
- 좋은 점수: 0.1 이하, 개선 필요: 0.25 초과
이미지 로딩 시 크기 변화로 인한 레이아웃 시프트 발생
- FID (First Input Delay): 180ms
- 사용자가 페이지와 처음 상호작용할 때의 응답 시간
- 좋은 점수: 100ms 이하, 개선 필요: 300ms 초과
- 대용량 이미지 로딩으로 인한 메인 스레드 블로킹 영향
자동화 시스템 구성
</h2>이미지 최적화 도구 설치
</h3>1
2
3
4
5
# 이미지 최적화 도구 설치
brew install pngquant jpegoptim
# 설치 확인
which pngquant && which jpegoptim
자동 최적화 스크립트 생성
</h3>- 파일 생성 위치
- 프로젝트 루트 디렉토리에
auto-optimize-images.js
파일 생성 - 실행 권한 부여
1
chmod +x auto-optimize-images.js
- 프로젝트 루트 디렉토리에
auto-optimize-images.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); // 설정 const IMG_DIR = 'assets/img'; const QUALITY = 85; const SKIP_FAVICONS = true; // 이미지 최적화 함수 function optimizeImage(filePath) { const ext = path.extname(filePath).toLowerCase(); try { if (ext === '.png') { execSync(`pngquant --force --ext .png --quality=65-${QUALITY} "${filePath}"`, { stdio: 'ignore' }); } else if (ext === '.jpg' || ext === '.jpeg') { execSync(`jpegoptim --max=${QUALITY} --strip-all "${filePath}"`, { stdio: 'ignore' }); } return true; } catch (error) { return false; } } // 새로 추가된 이미지 파일 찾기 function getNewImages() { try { const addedFiles = execSync('git diff --cached --name-status', { encoding: 'utf8' }); const newImages = []; const lines = addedFiles.split('\n'); lines.forEach(line => { if (line.startsWith('A\t') && line.includes(IMG_DIR)) { const filePath = line.substring(2); const ext = path.extname(filePath).toLowerCase(); if (['.png', '.jpg', '.jpeg'].includes(ext)) { if (!SKIP_FAVICONS || !filePath.includes('favicon')) { newImages.push(filePath); } } } }); return newImages; } catch (error) { return []; } } // 메인 실행 function main() { console.log('이미지 자동 최적화 시작...'); const newImages = getNewImages(); if (newImages.length === 0) { console.log('최적화할 새 이미지가 없습니다.'); return; } console.log(`${newImages.length}개의 새 이미지를 발견했습니다.`); let optimized = 0; let failed = 0; newImages.forEach(imagePath => { console.log(`최적화 중: ${imagePath}`); if (optimizeImage(imagePath)) { optimized++; console.log(`완료: ${imagePath}`); } else { failed++; console.log(`실패: ${imagePath}`); } }); console.log(`최적화 완료: ${optimized}개 성공, ${failed}개 실패`); if (optimized > 0) { console.log('최적화된 파일들을 Git에 다시 추가합니다...'); try { execSync(`git add ${newImages.join(' ')}`, { stdio: 'ignore' }); console.log('Git에 추가 완료!'); } catch (error) { console.log('Git 추가 실패:', error.message); } } } main();
Git 훅 설정
</h3>- 파일 생성 위치
.git/hooks/pre-commit
파일 생성- 실행 권한 부여
1
chmod +x .git/hooks/pre-commit
pre-commit 훅
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#!/bin/bash # 자동 이미지 최적화 Git 훅 echo "이미지 최적화를 확인합니다..." # Node.js가 설치되어 있는지 확인 if ! command -v node &> /dev/null; then echo "Node.js가 설치되어 있지 않습니다. 이미지 최적화를 건너뜁니다." exit 0 fi # 이미지 최적화 도구가 설치되어 있는지 확인 if ! command -v pngquant &> /dev/null || ! command -v jpegoptim &> /dev/null; then echo "이미지 최적화 도구가 설치되어 있지 않습니다." echo "다음 명령어로 설치하세요: brew install pngquant jpegoptim" exit 0 fi # 자동 최적화 스크립트 실행 node auto-optimize-images.js echo "이미지 최적화 완료!"
실시간 파일 감시 스크립트
</h3>- 파일 생성 위치
- 프로젝트 루트 디렉토리에
watch-images.js
파일 생성 - 실행 권한 부여
1
chmod +x watch-images.js
- 프로젝트 루트 디렉토리에
watch-images.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); // 설정 const IMG_DIR = 'assets/img'; const QUALITY = 85; // 이미지 최적화 함수 function optimizeImage(filePath) { const ext = path.extname(filePath).toLowerCase(); try { if (ext === '.png') { execSync(`pngquant --force --ext .png --quality=65-${QUALITY} "${filePath}"`, { stdio: 'ignore' }); } else if (ext === '.jpg' || ext === '.jpeg') { execSync(`jpegoptim --max=${QUALITY} --strip-all "${filePath}"`, { stdio: 'ignore' }); } return true; } catch (error) { return false; } } // 파일 감시 시작 function startWatching() { console.log('이미지 파일 감시를 시작합니다...'); console.log('감시 디렉토리:', IMG_DIR); console.log('품질 설정:', QUALITY + '%'); console.log('종료하려면 Ctrl+C를 누르세요\n'); fs.watch(IMG_DIR, { recursive: true }, (eventType, filename) => { if (eventType === 'rename' && filename) { const filePath = path.join(IMG_DIR, filename); const ext = path.extname(filename).toLowerCase(); if (['.png', '.jpg', '.jpeg'].includes(ext)) { setTimeout(() => { if (fs.existsSync(filePath)) { console.log(`새 이미지 발견: ${filename}`); if (optimizeImage(filePath)) { console.log(`최적화 완료: ${filename}`); } else { console.log(`최적화 실패: ${filename}`); } } }, 1000); } } }); } startWatching();
사용 방법
</h2>Git 훅 방식
</h3>1
2
3
4
# 이미지 추가 후 커밋하면 자동으로 최적화됨
git add assets/img/new-image.png
git commit -m "새 이미지 추가"
# 자동으로 최적화 후 커밋됨
수동 실행
</h3>1
2
# 새로 추가된 이미지만 최적화
npm run auto-optimize
실시간 감시
</h3>1
2
# 터미널에서 실행하면 이미지 추가 시 실시간 최적화
npm run watch-images
package.json 설정
</h3>- 파일 생성 위치
- 프로젝트 루트 디렉토리의
package.json
파일에 scripts 섹션 추가 - 기존 scripts 섹션이 있다면 해당 내용을 추가
- 프로젝트 루트 디렉토리의
- package.json
1 2 3 4 5 6 7 8 9 10
{ "scripts": { "build": "gulp build", "dev": "gulp dev", "optimize-images": "node optimize-images-safe.js", "auto-optimize": "node auto-optimize-images.js", "watch-images": "node watch-images.js", "test": "echo 'Testing blog functionality...'" } }
성능 최적화 결과
</h2>최적화 전후 비교
</h3>용량 최적화 결과
1 2 3 4 5 6 7
# 최적화 전 du -sh assets/img # 결과: 149M assets/img # 최적화 후 du -sh assets/img # 결과: 45M assets/img
페이지 로딩 시간 개선 (Chrome DevTools 기준)
페이지 유형 최적화 전 최적화 후 개선율 이미지 중심 포스트 3-5초 1-2초 60-70% 일반 포스트 2-3초 0.8-1.5초 50-60% 메인 페이지 4-6초 1.5-2.5초 60-70%
Core Web Vitals 개선 효과
</h3>- Lighthouse 성능 점수
- 최적화 전
- Performance: 65-70점
- LCP: 3.2초
- CLS: 0.15
- FID: 180ms
- 최적화 후
- Performance: 85-90점
- LCP: 1.8초 (44% 개선)
- CLS: 0.05 (67% 개선)
- FID: 95ms (47% 개선)
- 최적화 전
최적화 결과 요약
</h2>핵심 성과
</h3>항목 | 최적화 전 | 최적화 후 | 개선율 |
---|---|---|---|
이미지 용량 | 149MB | 45MB | 70% 감소 |
페이지 로딩 시간 | 3-5초 | 1-2초 | 60-70% 단축 |
Lighthouse 점수 | 65-70점 | 85-90점 | 20-25점 향상 |
LCP | 3.2초 | 1.8초 | 44% 개선 |
CLS | 0.15 | 0.05 | 67% 개선 |
FID | 180ms | 95ms | 47% 개선 |
적용된 기술
</h3>- 이미지 압축
- pngquant, jpegoptim
- 자동화
- Git pre-commit 훅
- 모니터링
- Lighthouse, Chrome DevTools
- 스크립트
- Node.js 기반 최적화 도구
트러블슈팅
</h2>자주 발생하는 문제와 해결 방법
</h3>- 이미지 최적화 도구 설치 오류
- 문제
pngquant
또는jpegoptim
명령어를 찾을 수 없음
1 2 3
# 오류 메시지 command not found: pngquant command not found: jpegoptim
해결 방법
1 2 3 4 5
# macOS brew install pngquant jpegoptim # Ubuntu/Debian sudo apt-get install pngquant jpegoptim
- 문제
- Git 훅 실행 권한 문제
- 문제
- pre-commit 훅이 실행되지 않음
1 2
# 오류 메시지 .git/hooks/pre-commit: Permission denied
해결 방법
1 2 3 4 5
# 실행 권한 부여 chmod +x .git/hooks/pre-commit # 권한 확인 ls -la .git/hooks/pre-commit
- 문제
- 이미지 최적화 실패
문제: 일부 이미지 파일이 최적화되지 않음
- 원인 분석
- 손상된 이미지 파일
- 권한 문제
- 디스크 공간 부족
- 해결 방법
1 2 3 4 5 6 7 8 9
# 이미지 파일 무결성 확인 file assets/img/problematic-image.png # 권한 확인 및 수정 chmod 644 assets/img/*.png chmod 644 assets/img/*.jpg # 디스크 공간 확인 df -h
- Node.js 버전 호환성 문제
- 문제
- 스크립트 실행 시 Node.js 버전 오류
- 해결 방법
1 2 3 4 5 6
# Node.js 버전 확인 node --version # nvm을 사용한 버전 관리 nvm install 16 nvm use 16
- 문제
- Git 훅이 실행되지 않는 문제
- 문제
- pre-commit 훅을 설정했지만 이미지 최적화가 실행되지 않음
- 원인 분석
- Git 훅이 비활성화되어 있음
- 훅 파일이 올바른 위치에 없음
- Git 설정에서 훅이 무시됨
- 해결 방법
1 2 3 4 5 6 7 8 9 10 11 12
# Git 훅 활성화 확인 git config core.hooksPath # 훅 파일 위치 확인 ls -la .git/hooks/pre-commit # Git 훅 경로 설정 (필요시) git config core.hooksPath .git/hooks # 훅 테스트 git add assets/img/test-image.png git commit -m "훅 테스트"
- 문제
- 이미지 품질 최적화 문제
- 문제
- 최적화 후 이미지 품질이 너무 낮아짐
- 일부 이미지에서 아티팩트 발생
- 원인 분석
- 압축 품질 설정이 너무 낮음 (85%)
- 이미지 유형에 따른 최적화 설정 부족
- 원본 이미지 품질 문제
- 해결 방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 품질 설정 조정 (auto-optimize-images.js 수정) const QUALITY = 90; // 85에서 90으로 상향 조정 # 이미지 유형별 품질 설정 if (ext === '.png') { // PNG는 더 높은 품질 유지 execSync(`pngquant --quality=80-95 "${filePath}"`); } else if (ext === '.jpg' || ext === '.jpeg') { // JPEG는 적당한 품질 execSync(`jpegoptim --max=90 "${filePath}"`); } # 원본 이미지 품질 확인 identify -verbose assets/img/sample-image.jpg
- 문제
Reference
</h2>A new version of content is available.
1
2
</div>
</article>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
### 메뉴 커스터마이징
- Chirpy 테마 메뉴 관리
- `_tabs` 디렉토리에서 관리
- 기본 메뉴
- about.md, archives.md, categories.md, tags.md
- 새 메뉴 추가하기
- _tabs 디렉토리에 새 파일 생성
- 예: projects.md
- Front Matter 설정
```yaml
---
layout: page
title: Projects
icon: fas fa-folder
order: 5
---
# Projects
- 여기에 프로젝트 내용 작성
```
- order 값으로 메뉴 순서 조정
- 숫자가 작을수록 왼쪽에 배치
- 기본 메뉴들의 order 값 참고
- 아이콘 변경
- Font Awesome 아이콘 사용
- [Font Awesome Icons](https://fontawesome.com/icons) 참고
## 트러블슈팅
### 자주 발생하는 문제와 해결 방법
#### Ruby 버전 호환성 문제
- 문제 상황
- Jekyll 빌드 시 Ruby 버전 오류 발생
```bash
# 오류 메시지
Error: Your Ruby version is 2.7.0, but your Gemfile specified ~> 3.0
```
- 해결 방법
- rbenv로 Ruby 버전 변경
```bash
# 설치 가능한 Ruby 버전 확인
rbenv install -l
# 필요한 버전 설치 (Gemfile 요구사항에 맞는 버전)
rbenv install [버전번호]
# 프로젝트에 Ruby 버전 설정
rbenv local [버전번호]
# 버전 확인
ruby -v
# Bundle 재설치
bundle install
```
#### Bundler 버전 충돌
- 문제 상황
- Gemfile.lock에 명시된 Bundler 버전과 설치된 버전이 다름
```bash
# 오류 메시지
Bundler could not find compatible versions for gem "bundler"
```
- 해결 방법
```bash
# Bundler 업데이트
gem install bundler
bundle install
# 또는 Gemfile.lock 삭제 후 재생성
# Windows PowerShell: Remove-Item Gemfile.lock
# Git Bash / Mac / Linux: rm Gemfile.lock
bundle install
# 또는 특정 버전 설치 후 사용 (Gemfile.lock에 명시된 버전)
gem install bundler -v [버전번호]
bundle install
포트 충돌 오류
- 문제 상황
- 4000번 포트가 이미 사용 중
1 2
# 오류 메시지 Address already in use - bind(2) for 127.0.0.1:4000
- 4000번 포트가 이미 사용 중
- 해결 방법
1 2 3 4 5 6 7 8 9
# 다른 포트로 실행 bundle exec jekyll serve --port 4001 # 또는 기존 프로세스 종료 (Windows) netstat -ano | findstr :4000 taskkill /PID [프로세스ID] /F # 또는 기존 프로세스 종료 (Mac/Linux) lsof -ti:4000 | xargs kill -9
파일 변경사항이 반영되지 않음
- 문제 상황
- 파일 수정 후 변경사항이 보이지 않음
- LiveReload가 작동하지 않음
- 해결 방법
1 2 3 4 5 6 7 8 9 10
# 캐시 삭제 후 재실행 bundle exec jekyll clean bundle exec jekyll serve --livereload # 브라우저 캐시 강제 새로고침 # Windows: Ctrl + Shift + R # Mac: Cmd + Shift + R # _config.yml 변경 시 서버 재시작 필요 # Ctrl + C로 중단 후 다시 실행
이미지가 표시되지 않음
- 문제 상황
- Markdown에 이미지 추가했지만 화면에 나타나지 않음
- 원인 분석
- 이미지 경로 오류
- 파일 이름 대소문자 불일치
- 상대 경로 문제
- 해결 방법
- 절대 경로 사용 권장
- 올바른 방법
1

- 잘못된 방법
1

- 올바른 방법
- 파일 이름 확인
- Linux/Mac은 대소문자 구분
- sample.jpg ≠ Sample.jpg
- 이미지 파일 존재 확인
- 파일 탐색기에서 assets/img 디렉토리 확인
- 파일 이름과 경로가 정확한지 확인
- 절대 경로 사용 권장
GitHub Pages 배포 실패
- 문제 상황
- Push 후 사이트가 업데이트되지 않음
- GitHub Actions에서 빌드 실패
- 해결 방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 1. Actions 탭에서 오류 로그 확인 # GitHub Repository > Actions 탭 클릭 # 실패한 워크플로우 클릭하여 로그 확인 # 2. 로컬에서 빌드 테스트 bundle exec jekyll build # 3. Gemfile.lock 커밋 확인 git add Gemfile.lock git commit -m "Update Gemfile.lock" git push origin main # 4. GitHub Pages 설정 재확인 # Settings > Pages > Source 확인
Liquid 문법 오류
- 문제 상황
- 포스트에서 중괄호 사용 시 빌드 오류
1 2
# 오류 메시지 Liquid Exception: Liquid syntax error
- 포스트에서 중괄호 사용 시 빌드 오류
- 해결 방법
- Liquid 문법 이스케이프
- raw 태그 사용
1 2 3
{{ 중괄호 내용을 그대로 표시 }}
- raw 태그 사용
- 코드 블록에서 자동 이스케이프
- 백틱 3개로 감싸기
1
print("")
- 백틱 3개로 감싸기
- Liquid 문법 이스케이프
한글 깨짐 문제
- 문제 상황
- Windows에서 한글이 깨져서 표시됨
- 해결 방법
1 2 3 4 5 6 7 8 9 10
# 파일 인코딩을 UTF-8로 저장 # VSCode 설정 # File > Preferences > Settings # "files.encoding": "utf8" 확인 # PowerShell 인코딩 설정 chcp 65001 # _config.yml에 인코딩 명시 encoding: utf-8
성능 최적화 팁
이미지 최적화
- 이미지 압축 도구 사용
- 도구 설치
1 2 3 4 5 6 7 8 9
# macOS brew install pngquant jpegoptim # Ubuntu/Debian sudo apt-get install pngquant jpegoptim # Windows # pngquant: https://pngquant.org/ # jpegoptim: Linux/Mac 전용, Windows는 온라인 도구 사용 권장
- 이미지 압축 실행
1 2 3 4 5
# PNG 압축 pngquant --quality=65-80 assets/img/*.png # JPEG 압축 (Mac/Linux) jpegoptim --max=85 assets/img/*.jpg
- 도구 설치
- WebP 형식 사용
- 변환 도구 설치
1 2 3 4 5 6 7 8 9
# macOS brew install webp # Ubuntu/Debian sudo apt-get install webp # Windows # Google WebP 공식 사이트에서 다운로드 # https://developers.google.com/speed/webp/download
- 이미지 변환
1
cwebp -q 80 input.jpg -o output.webp
- 변환 도구 설치
빌드 시간 단축
- Incremental 빌드 활성화
1
bundle exec jekyll serve --incremental
- 주의사항
- 불안정할 수 있으며 변경사항이 누락될 수 있음
- 파일 수정이 제대로 반영되지 않으면
jekyll clean
후 재실행 권장 - 프로덕션 빌드에서는 사용하지 않는 것을 권장
- 주의사항
- 불필요한 플러그인 비활성화
- _config.yml에서 사용하지 않는 플러그인 제거
- 개발 환경 설정
- _config.yml 파일 분리
1 2 3 4 5
# _config.yml (프로덕션) environment: production # _config_dev.yml (개발) environment: development
- 개발 환경으로 실행
1
bundle exec jekyll serve --config _config.yml,_config_dev.yml
- _config.yml 파일 분리
유용한 명령어 정리
Jekyll 명령어
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 새 Jekyll 사이트 생성
jekyll new my-blog
# 개발 서버 실행
bundle exec jekyll serve
# LiveReload로 실행
bundle exec jekyll serve --livereload
# 미래 날짜 포스트 포함
bundle exec jekyll serve --future
# 다른 포트로 실행
bundle exec jekyll serve --port 4001
# 증분 빌드 (주의: 불안정할 수 있음)
bundle exec jekyll serve --incremental
# 상세 로그 출력
bundle exec jekyll serve --verbose
# 빌드만 실행 (서버 미실행)
bundle exec jekyll build
# 캐시 삭제
bundle exec jekyll clean
# 버전 확인
bundle exec jekyll -v
Git 명령어
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 저장소 클론
git clone https://github.com/username/username.github.io.git
# 상태 확인
git status
# 변경사항 추가
git add .
git add filename
# 커밋
git commit -m "커밋 메시지"
# 푸시
git push origin main
# 풀
git pull origin main
# 브랜치 생성 및 전환
git checkout -b new-branch
# 브랜치 목록 확인
git branch
# 로그 확인
git log --oneline
# 변경사항 되돌리기
git checkout -- filename
Bundle 명령어
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 의존성 설치
bundle install
# 의존성 업데이트
bundle update
# 특정 gem 업데이트
bundle update jekyll
# 설치된 gem 목록
bundle list
# gem 정보 확인
bundle info jekyll
# 실행 환경 확인
bundle env
# Gemfile.lock 삭제 후 재생성
# Windows PowerShell
Remove-Item Gemfile.lock
bundle install
# Git Bash / Mac / Linux
rm Gemfile.lock
bundle install