0. 개요
CMS는 대부분의 개발자가 가장 먼저 접하는 친숙한 구조입니다. CRUD를 기반으로 한 패턴으로 어떤 기술을 배우든 자연스럽게 마주하게 되죠. 라프텔, 넷플릭스, 네이버 쇼핑, 다음 웹툰, 링크드인까지 우리가 쓰는 대부분의 서비스도 사실상 CMS의 확장 버전이라 볼 수 있습니다.
가장 단순해 보이지만, 그만큼 끝 없이 파고들 수 있는 구조로 그동안 당연하게 써왔지만 정리를 해본 적이 없었네요. 이번에 처음으로 쭉 정리해봤습니다, 부족한 점이 있다면 가감 없이 피드백 부탁 드려요
1. 콘텐츠 CRUD
1.1 생성 (Create)
- SEO용 slug 자동 생성 (핵심 키워드, stop word 제거, 소문자 사용, 특수문자 제거)
- XSS, SQL Injection 검증
- 캐시 데이터에 추가
- 스케줄링 처리: 작은 작업은 cron을, 대용량은 메시지 큐(Kafka, BullMQ)를 사용하여 백그라운드 작업
- 자동화 테스트: CRUD API가 정상적으로 작동하는 지를 CI/CD 파이프라인에 포함하여 매번 체크
- 다양한 플랫폼 지원: 부 모바일/TV 앱이 동일 API 사용 가능 형태로 설계
- 요금제 플랜: Redis를 이용해서 계정마다 현재 접속 수 체크해서 요금제 플랜에 맞게 관리
- 모니터링: 업로드 실패율, 렌더링 지연, 승인 리뷰 대기 시간, 서버 리소스 등 수치 트래킹
- sentry: 모니터링 도구로 실시간 에러 트래킹과 프론트, 백엔드에서 발생하는 예외, 로그, 버그 정보를 수집하여 UI로 시각화 해줌
- datadog: 서버, 애플리케이션, 로그, 메트릭, 인프라를 통합 모니터링 툴로 sentry보다 범용적이며 DevOps에서 많이 사용됨
- 리소스 파일 업로드: 리소스 파일들을 Multipart Upload Protection, 즉 chunk 단위로 업로드해서 악성파일, 과도한 용량문제 해결, 보안 룰 적용 (확장자, MIME 타입, 바이러스 검사)
- API 문서화: drf-spectacular 같은 걸로 자동 문서화
1.2 읽기 (Read)
- 상태, 태그와 같은 조건에 따라 필터링된 대용량 데이터에 대한 쿼리 캐시 지원
- 공개된 데이터는 Redis / Memcached로 select list를 캐싱
- 변경시는 수동으로 캐시를 지우거나 TTL이 짧다면 자동 갱신
- 비디오/이미지/정적 리소스는 CDN으로 읽기 비용 감소
- 발행이 Draft로 콘텐츠여도 미리보기 링크로 확인 가능
1.3 수정 (Update)
- 업데이트 충돌 방지를 위해, Optimistic Concurrency로 글을 수정을 진행할 때와 가져온 글 버전과 저장할 떄 글 버전이 같아야 함
- slug나 파일 링크 변경시 유효한지 검사
- 변경전 슬러그도 지원하기 위한 alias 기능
- 콘텐츠 변경시 이전 버전들을 저장해서 글의 버전 관리
- 비디오 파일이 바뀌면 자동으로 썸네일 재생성
- 콘텐츠가 업데이트되면 관련 select 캐시나 cdn 캐시 데이터 수정
- 콘텐츠 수정 시 어떤 Text가 바뀐지를 Diff 뷰로 보여줌
1.4 삭제 (Delete)
- Deleted At 또는 Disabled로 soft 삭제를 하고, 추후에 관리자나 유저가 DB에서 완전 삭제후 자동 purge
- soft 삭제로 db 리소스 접근을 최소 화하는 방법으로 좋아요나 이모지 같이 사용자가 장난 칠 수 있는 기능에 적합
- 연관 데이터, 댓글, 조회수/통계 테이블, 썸네일, 원본 정적 리소스 파일간의 관계 제거
- soft 삭제의 경우 복원 가능
- 누가, 언제, 어떻게 삭제했는 지를 기록
- 삭제된 콘텐츠로 접근 시 301로 리디렉트하거나 404로 반환
2. 콘텐츠 관리
2.1 콘텐츠 상태 관리
- 발행 관리: Draft, Published, Scheduled
- 시간 관리: Updated At, Created At
2.2 동영상 콘텐츠
- 실시간 방송 스트리밍 (단방향 실시간 통신)
- 장르, 태그, 시리즈, 년도(분기), 현재 방영 여부, 출시타입(TAV,극장판 OVA)로 영상 콘텐츠 분리
- 현재 방영 작은 요일별 신작으로 확인 가능하게 분리
- 원할한 스트리밍 서비스를 위한 캐싱이나 인코딩 처리 필요
2.3 콘텐츠 일정 설정
- 예약 게시일 등록
- 콘텐츠에 유효기간이 있다면 만료일도 등록
2.4 팀 기반 콘텐츠 작성자 관리 (PD, 편집자, 운영자)
- 권한별로 접근할 수 있는 메뉴, 페이지 분리
3. 데이터 보안
3.1 데이터 암호화
- 암호화 대상: 개인정보 (주민등록번호, 이름, 이메일, 비밀번호 등)
- 암호화 방법
- 대칭키 암호화: 암복호화에 같은 키 사용, 빠르고 효율적
- 대상: 이메일, 주소, 이름 등 자주 조회 및 수정이 필요한 데이터
- 암호화: AES-256, AES-GCM
- 비대칭키 암호화: 공개키로 암호화, 개인키로 복호화하고 느리지만 공개 키 배포 가능
- 대상: 민감한 서명, 토큰, 공개키 기반 인증 구조 (JWT, OAuth, SSH 등)
- 암호화: RSA
- 비밀번호는 복호화가 불가능한 해시 알고리즘 채택 (bcrypt, scrypt)
- 대칭키 암호화: 암복호화에 같은 키 사용, 빠르고 효율적
- 암호화 레이어 별 특징
- 애플리케이션 레벨: 코드에서 작업하므로 필드 단위로 세밀한 제어가 되지만 코드의 복잡잡도 증가
- DB 레벨 (TDE): 전체 테이블/디스크를 설정만으로 암호화가 되지만 필드 제어가 불가능하고 느림
- 하이브리드: 민감한 데이터는 앱단에서 나머지는 TDE로 진행하면 성능과 보안의 밸런스를 조절할 수 있지만 설정에 복잡도 증가
- 키 관리: 암호화 키는 별도의 키 시스템으로 관리 ex: AWS KMS
- 참고 사항:
- 암호화된 데이터는 로그에 찍으면 안됨
- 잦은 검색 조건이 있는 건 인덱스 때문에 암호화 지양하고 민간함 정보만 암호화화
- 환경에 맞게 코드 컨밴션 툴 사용해서 코드 스타일 유지
- Python의 black, PEP8 스타일 가이드 준수
- Python의 isort, import 정렬기로 black과 같이 사용
4. 동영상 업로드 및 변환
4.1 동영상 업로드 시나리오
- 업로드 → 인코딩 → 썸네일 생성 → 배포
4.2 인코딩 포맷
- MP4: 범용 포멧으로 대부분의 브라우저에서 지원하지만 스트리밍에서 성능이 제한적
- HLS(HTTP Live Streaming): Apple 주도로 ios 친화적 스트리밍에 적합하고 현재는 다양한 장치에서 지원
- DASH (MPEG-DASH): MPEG 표준, 크롬/안드로이드 친화적이고 유연한 확장성 제공
- 보통 두 가지 스트리밍 포맷(HLS & DASH)을 생성하고 클라이언트에서 상황에 맞춰 제공
4.3 Resumable Upload (중단 후 다시 업로드)
- tus(open protocol, 업로드 중단/복원 대응 강력), multipart upload, chunked upload 방식 사용
- AWS S3 multipart upload도 해당 기능을 제공하니 클라우드를 활용
- 클라이언트에서 chunk 관리를 위해 JS 기반 상태 저장 로직 필요
4.4 자동 해상도 변환 (240p~4K)
- 하나의 동영상을 다양한 해상도 변환해서 저장 (360p, 480p, 720p, 1080p, 1440p, 4K)
- 자동 트랜스코딩 워크플로우는 큐 기반으로 비동기 처리
4.5 썸네일 자동 생성
- 프레임 수 기준 중간 지점이나 가장 밝은 장면 등 다양한 조건으로 썸네일 생성
- AI 기반 썸네일 추출 기능
- 관리자 수동 업로드도 지원
4.6 FFmpeg + Redis + Worker 기반 트랜스코딩 큐
업로드된 파일은 곧바로 트랜스코딩하지 않고 큐에 등록 후 비동기 처리
FFmpeg로 동영상 인코딩, 트랜스코딩
- FFmpeg(Fast Forward MPEG): 오픈소스로 멀티미디어 데이터의 인코딩, 디코딩, 변환, 필터링, 스트리밍 등을 처리
기능 설명 포맷 변환 .mp4 → .webm
,.avi → .mp4
등코덱 변환 예: H.264, AAC, Opus 등으로 인코딩/디코딩 자르기/합치기 영상 자르기, 오디오 합치기 등 오디오 추출 영상에서 음성만 추출 ( -vn
옵션)해상도/프레임 조정 영상 리사이즈, 프레임 속도 변경 등 썸네일 추출 특정 시점의 이미지 캡처 라이브 스트리밍 RTMP, HLS 등으로 방송 가능
- FFmpeg(Fast Forward MPEG): 오픈소스로 멀티미디어 데이터의 인코딩, 디코딩, 변환, 필터링, 스트리밍 등을 처리
docker로 worker를 여러개 띄우고 Redis에서 중앙 큐 역할을 하며 여러 서버에서 중복없이 병렬로 프로세스 처리
[User Upload]
↓
[Web Server] → Redis.enqueue(job)
↓
[Worker Node] → FFmpeg 실행 → 상태 업데이트
↓
[Database] → status: success, output files 등록
4.7 업로드 파일명 유니크화 (해시 기반)
- 중복 가능성을 없애기 위해 SHA256, UUID, ULID 등으로 이름 변환
5. 스트리밍 최적화
5.1 기본 스트리밍 기능
- 청크로 불러온 영역을 동영상 플레이어로 표시
- 정적 자산 CDN 캐싱 (Cloudflare, CloudFront, Fastly 등)
- 영상 미리보기, 챕터 미리보기 썸네일
- 미리보기 썸네일 타임라인 사전 로딩
- 네트워크 상태 기반 화질 자동 조절
5.2 Resolution/Bitrate 밸런싱
- 해상해상도와 비트레이트를 조절해서 저장/전송
- 해상도만 높고 비트레이트가 낮으면 화질 뭉개짐
- 해상도는 낮은데 비트레이트가 너무 높으면 쓸데없이 용량만 큼
- 둘 다 너무 높으면 고화질이지만 저장공간,전송속도에서 낭비가 발생함함
5.3 Seek 구간 기반 Chunk prefetching
- 사용자가 특정 위치로 00:05:00으로 이동 시 버퍼링 없이 재생되게 하기 위한 기능
- 사용자들이 많이 본 구역의 청크를 미리 패치
5.4 DRM 적용
- DRM(Digital Rights Management): 동영상 불법 다운로드/복제를 막기 위한 콘텐츠 보호 기술
- 사용자가 동영상을 스트리밍 하되 파일로 추출하거나 복사하지 못하도록 하는 거
- Widevine: Google이 만든 DRN, Youtube, Netflix, Disney+ 등에 사용
- FairPlay: Apple이 만든 DRN, Safari, ios, macOS 기반의 Apple TV에서 사용
6. 사용자 경험 (UX)
- 자막 스타일 선택 기능 추가
- 다국어 지원
- 영상 내 챕터 구간/타임라인 설정
- 구간 댓글, 타임 라인 하이라이트
- 시청 기록 저장 + 이어보기
- 북마크, 재생목록, 좋아요/싫어요 반응 기능
7. 통계
- 조회수, 재생 시간, 이탈 지점 시각화
- 유입 경로 분석
- 사용자별 시청 이력 추적
- 영상별 대시보드 제공
- A/B 테스트 기반 영상 효과 측정
- 어떤 썸네일 타이틀이 더 효과적인가를 테스트
- 사용자별 맞춤형으로 썸네일을 노출 시키는 기능까지 연계
8. 댓글/반응 시스템
- 대댓글, 실시간 채팅 (라이브용)
- 타임스탬프 댓글
- 이모지 반응 (👍 😂 😢 🔥 등)
- 댓글 자체에 대한 좋아요 같은 기능
- 1인 1회 같은 룰 필요
- 댓글 내용으로써 넣는 이모지 기능
- DB에 저장할 때 shortcode 정의
- charset을 utf8mb4 인코딩
- Redis 등으로 집계 수를 캐싱하여 빠른 렌더링 가능
- 사용자가 요청을 보내면 서버스는 이를 받고 먼저 Reids 체크 후 현재 상태를 서비스에 알려준 뒤 서비스는 상황에 따라 분로직 실행
- Redis 체크 할 때 원자성으로 로직이 실행 (ex: 읽고 쓰기, 쓰기, 읽기, 쓰고 읽기 등등)
- 좋아요 기능이나 이모지는 Redis에 쓰고 읽음
- 이모지는 UTF-8로 인코딩 통일
- DB는 utf8mb4
- 최신 유니코드 대응 여부 검토
- OS나 브라우저에 따라 미지원하는 경우도 있기에 웹 폰트(Noto Color Emoji)나 이미지(Twemoji) 방식 고려
- 댓글 자체에 대한 좋아요 같은 기능
- 스팸 필터, 신고, 차단 기능
- 특정 사용자가 짧은 시간 내에 과도한 댓글 작성이나 이모지 이벤트 일 경우 차단
- 모델 학습을 통한 스팸 데이터 분류
- 금지어 사전 관리용 Redis 키 구조
9. 알림 시스템
- 실시간 알림 (WebSocket)
- 사용자한테 이메일/앱 푸시 알림
- 사용자가 본 콘텐츠를 분석하여 추천 콘텐츠 시스템 도입
- 사용자가 봤던 콘텐츠의 업데이트 소식 알림
- 채널/태그 구독 알림
- 실패 알림 재전송 기능
- 마케팅/반응 유도용 알림에 대한 사용자 설정 추가
10. 파일 및 CDN 처리
10.1 이미지 최적화
- AVIF는 JPEG/WebP 대비 최대 10배 압축 효율, HDR,투명도,애니메이션 등 지원
- WebP는 여전히 레거시 브라우저 지원력 우수, 병목 없는 인코딩이 가능
10.2 CDN 활용
- Cloudflare, AWS CloudFront 등
- CloudFront에 경우 다수 cdn이 필요한 경우 계층형 캐시 아키텍쳐인 Origin Shield를 구상해서 대용량 콘텐츠, 다중 CDN 네트워크 구성에 유리
10.3 해시 기반 캐싱 및 버전 관리
- 정적 파일인 css, js, image가 롱 캐시된 채 사용자에게 보여지는 걸 방지하고자 이름을 해시 값으로 정의
- 이렇게 만들어진 해시는 버전 유지 기간만큼 지속됨
단계 설명 ① 빌드/인코딩 동영상 변환 + 썸네일 추출 + 해시 기반 네이밍 생성 ② 업로드 S3에 2중 폴더 구조 (video123/v1, /v2 등)로 업로드 ③ CDN Purge 새 hash 파일 배포 시 이전 해시 경로는 유지, 새 hash URL만을 배포 ④ 레거시 Clean-Up 일정 기간 후 삭제 플로우 (3개월 후 이전 version 제거) - CDN Purge 없이 해시가 바뀌면 자동으로 새로운 리소스로 인식되어 캐싱 혜택을 그대로 유지
10.4 Lazy Load + Placeholder
- Lazy‑Load와 Placeholder는 페이지 초기 로딩 속도와, 사용자 경험 개선
- 최신 브라우저의 img에 한해 loading=“lazy"로 지원 로딩 가능한데 이걸 통해 처음 보이는 이미지를 먼저 로딩되게 구성
- Placeholder는 실제 이미지가 로드될 때까지 임시 데이터 표시
11. 보안
- Signed URL, JWT 기반 비공개 영상 접근
- 워터마크 삽입 (사용자 정보 포함 가능)
- 도메인 기반 접근 제한
- DRM 및 다운로드 방지
- 비정상 접근 탐지
12. 관리자/에디터 도구
- 콘텐츠 대시보드 (검색, 필터, 정렬)
- 일괄 업로드, 일괄 삭제
- 승인 대기 콘텐츠 목록
- soft 삭제 콘텐츠 목록
- 작업 로그 관리 (누가, 언제, 무엇을)
- 카테고리, 태그, 요일별 콘텐츠 지정하는 기능
13. 큐 및 비동기 작업
13.1 시나리오
동영상 업로드 → FFmpeg 트랜스코딩 → 썸네일 생성 → CDN invalidation → 완료
│ │ │
업로드 후 이후 작업은 모두 큐에 넣고 비동기로 실행합니다.
13.2 트랜스코딩 큐 (FFmpeg Worker)
- 메시지 브로커: Redis (Celery), RabbitMQ, AWS SQS 등 선택 가능
- 우선순위 큐: 트랜스코딩 해상도 기준 480p → 720p → 1080p 순으로 정렬
- 중첩 작업 방지(ab-repeat):
video_id + resolution
기반 유일 키를 생성하여 중복 트랜스코딩 방지 (예: RedisSETNX
) - 병렬 트랜스코딩 실행:
- CPU: 코어 단위 작업 분산
- GPU: group 단위로 리소스 지정 (GPU-Group별로 큐 분리 가능)
- 리소스 고갈 방지:
- 자원 점유 선점 제한
- 할당량 기반 스케줄링
- 비정상 종료/실패 처리:
- 재시도 횟수 제한 + 지수 백오프
- 상태 관리 DB (
queued
,processing
,done
,failed
)로 추적
13.3 기타 큐
- 썸네일 생성 큐:
- 각 해상도에 맞는 프레임 타이밍에서 썸네일 생성
- 트랜스코딩 완료 후 종속적으로 enqueue
- CDN 캐시 무효화 큐:
- 썸네일 및 본 영상 URL에 대해 무효화 작업 수행
- 단일 CDN API 요청으로 병합 처리
- 후처리 파이프라인 통합 제어:
- 전체 작업을 종속 관계로 연결:
chain
/chord
/group
구조 사용 - 이전 작업 실패 시 다음 단계 미실행
- 전체 작업을 종속 관계로 연결:
13.4 큐 및 비동기 시스템 이슈 대응 전략
이슈 유형 | 설명 | 대응 방안 |
---|---|---|
데드락 | 자원 점유 순서가 꼬일 경우 작업이 서로 대기 | 자원 요청 순서 고정, 타임아웃, 자원 점검 기반 큐 |
라이브락 | 자원을 계속 양보하며 진행되지 않음 | 재시도 제한 + 지수 백오프 |
우선순위 기아 | 1080p 같은 낮은 우선순위 작업이 영원히 실행되지 않음 | 가중치 보정 우선순위 큐 |
중복 작업(ab-repeat) | 동일 영상/해상도 트랜스코딩이 중복 수행됨 | 작업 키 중복 제거 (video_id + resolution ) |
순서 불일치 | 1080p가 720p보다 먼저 완료되어 파이프라인 꼬임 | 종속 큐 처리 (chain 구조 적용) |
리소스 과점 | 특정 해상도 또는 유저 작업이 자원을 독점 | 워커 자원 제한, group 기반 분산 |
실패 전파 누락 | 트랜스코딩 실패 후에도 썸네일/CDN 처리 강행 | 단계별 상태 확인 후 작업 진행 |
비동기 누락 | 큐 enqueue 성공했지만 워커가 다운되어 작업 미수행 | watchdog / 상태 추적 DB / autoscaler 운영 |
병렬 워커 병목 | 워커 수 과다 또는 부족 | 큐 길이 기반 autoscaler / 자원 기준 워커 scaling |
13.5 큐 시스템 구성도 (개요)
[Upload 완료]
↓
[Queue: 트랜스코딩 (우선순위)]
↓
[Worker: FFmpeg]
↓
[Queue: 썸네일 생성]
↓
[Worker: 썸네일]
↓
[Queue: CDN Invalidate]
↓
[Worker: CDN 처리]
↓
[DB 상태 갱신 / 완료 알림]
14. 검색 및 추천
- Full-text 검색: 제목, 설명, 태그 등
- 자동 완성
- 검색창 입력 시 1~2글자부터 실시간 추천어 제공
- 인기 검색어 노출
- Elasticsearch / Meilisearch 도입
- 추천 시스템: 협업 필터링, 콘텐츠 기반 추천
- 유사 영상 제안, 이어보기 추천
- 언어 자동 변환, 동의어 확장
- SF = 공상과학 이런걸로 자동으로 변환해서 일치하는 항목 찾아줌
15. 조회수
- 실시간 조회수 카운팅
- Redis, Memcached 사용해서빠른 응답 속도 확보
- 일정 주기마다 DB로 반영 (배치 or pub/sub)
- 비정상 트래픽 필터링
- 동일 IP 반복 조회 차단
- User-Agent, 쿠키, 세션 기반 중복 조회 제거
- 비동기 업데이트 처리
- 조회 요청과 DB 업데이트 분리 (메시지 큐 활용)
- 화면에서만 조회수가 증가 된걸로 보이게 할지
- 조회수 기준 정의: 단순 페이지 로딩인지 특정 시간 이상 체류(ex: 5초 이상)
- 누락 방지: 브라우저 캐싱 등으로 요청이 누락되는 경우 고려해 이벤트 기반 처리
- 하이브리드: 적은 조회수는 DB로, 값이 커지면 별도의 메모리로
16. 페이지네이션
16.1 페이지네이션 방법
- offset(관리자단, 적은 데이터): 가장 간단한 구현법이고 데이터 점프가 용이하지만 데이터량이 많아질 수록 느려짐
- 30개 건너뛰고 10개 가져와라는걸 그대로 따르는 기능
- query: SELECT * FROM posts ORDER BY created_at DESC LIMIT 10 OFFSET 30;
- 장점: 임의 페이지 점프 가능, UI에 번호형으로 페이지네이션 정보 제공 가능, 군현이 단순, 디버깅 관리 용이
- 단점: offset이 클수록 성능 저하, db는 offset 이전의 row는 버리고 limit 값만 가져오기에 성능 저하가 발생, 이는 인덱싱이 있어도 마찬가지인게 구조 자체가 비효율적이기 때문
- keyset(피드, 댓글, 무한 스크롤링): 빠르고 성능이 좋지만 값의 점프가 불가능
- PK 또는 정렬 가능한 컬럼 기준으로 어디까지 봤는지를 기억해서 다음 데이터를 가져오기
- 1번째 쿼리: SELECT * FROM posts ORDER BY id DESC LIMIT 10; (id = 110 ~ 101 데이터 나온다고 가정)
- 2번째 쿼리: SELECT * FROM posts WHERE id < 101 ORDER BY id DESC LIMIT 10;
- 쿼리가 아닌 로직을 통해 어디까지 봤는 지를 기억해서 진행
- cursor(모바일 피드, API, REST API, 서비스 로직): keyset에 URL을 합친 형태로 커서의 관리가 필요하지만 서비스 로직에 사용하기 적합
- 정확히는 keyset의 한 형태로 next_token 같은 커서 정보를 넘겨서 다음 페이지를 요청하는 방식으로 내부는 keyset과 동일하지만 url에 정보를 담아서 처리하는 방식
- url의 특정(created_at)값을 인코딩해서 담아서 보내고 이를 받아서 keyset 방식처럼 사용
- 장점: offset 불필요, 페이지 중간에 데이터 삭제되도 괜찮음, 무한 스크롤링에 적합
- 단점: 임의 페이지 점프 불가능, 커서 기준 필드가 정렬이 가능해야하고 별도로 관리 해야함
- 페이지 점프가 필요하면 offset, 무한스크롤이면 커서
17. 반응형 및 앱 연동
- 모바일 최적 UI (세로 영상, 작은 컨트롤)
- PWA 지원
- iOS/Android 앱 연동
- Chromecast / AirPlay 지원
- PC 등도 지원
18. 퍼포먼스 및 SEO
18.1 사이트 랜더링 전략
SSR (Server-Side Rendering)
- 거의 모든 서버 사용하는 전통 적인 방식(HTML 템플릿 기반)
- 모든 페이지 요청 시 서버가 HTML을 생성
- 실시간 데이터 반영이 필요하거나 사용자별 콘텐츠 제공에 유리
- TTFB가 상대적으로 느리고 서버 부하 증가 가능성 있음
- ex: 관리자 페이지, 로그인 후 콘텐츠
SSG (Static Site Generation)
- 정적 사이트 생성기를 통해 언어 불문하고 구현 가능
- 빌드 타임에 정적 HTML을 생성하여 CDN에 배포
- 매우 빠른 로딩 속도와 캐싱 효율, 높은 SEO 성능
- 콘텐츠 변경 시 전체 재빌드 필요
- ex: 블로그, 제품 소개 페이지
ISR (Incremental Static Regeneration)
- Next.js 같은 js 프레임워크 방식
- 정적 페이지를 주기적으로 백그라운드에서 재생성
- 실시간성 + 성능 모두 고려 가능
- 영상 콘텐츠와 같은 자주 업데이트되는 페이지에 적합
구조 권장 예시
- 기본 구조: SSG
- 데이터 갱신 필요: ISR
- 사용자 맞춤형 콘텐츠: SSR
※이 부분은 고려해본적이 없어서 봐도 잘 모르 겠네요※
18.2 SEO 최적화
메타 태그 최적화
Open Graph, Twitter Card를 통해 SNS 공유 시 미리보기 콘텐츠 제어
JSON-LD 구조화 데이터로 검색엔진에 의미 있는 정보 제공Lazy Load 적용
이미지, 영상 등 리소스는 사용자 뷰포트에 진입 시 로드
렌더링 속도 개선 및 데이터 절약 효과 있음Intersection Observer 사용
Lazy Load를 효율적으로 제어하는 브라우저 API
이미지, 광고, 무한 스크롤 등에 적용
자동 지원이 되지 않는 구형 브라우저는 polyfill 필요
18.3 Web Vitals 최적화 (LCP, CLS, INP)
Web Vitals: 페이지가 로드될 때 “리소스가 큰 걸(이미지, 텍스트 등)” 화면에 표시 되는 데 걸리는 시간
LCP (Largest Contentful Paint)
- 목표: 2.5초 이하
- 주요 이미지나 텍스트 콘텐츠의 렌더링 속도를 개선
- 초기 렌더링 리소스를 우선 로딩하고 차단 리소스 최소화
CLS (Cumulative Layout Shift)
- 목표: 0.1 이하
- 예상치 못한 레이아웃 이동 방지
- 모든 요소에 명확한 크기 지정
- 이미지, 광고, 동적 콘텐츠 영역에는 고정 영역 확보 필요
INP (Interaction to Next Paint)
- 목표: 200ms 이하
- 사용자 인터랙션 후 빠른 응답 및 렌더링 유지
- 초기 JS 번들 최적화 및 비동기 처리 강화
- 렌더링 부담이 큰 동작은 유휴 시간 또는 애니메이션 프레임에 처리
19. iframe 활용 전략
19.1 상황
- 레거시 시스템 통합
- 서드파티 위젯 사용
- 마이크로프론트엔드 구성
- 보안 격리
- 성능 분리
19.2 바닐라 JS + HTML
- 정적/동적 iframe 생성
- postMessage 통신
- 로딩/에러 처리
- 생명주기 관리
- 장점
- 기술적 격리
- 레거시 통합 및 팀 분리
- 기술 스택 자유도
- 배포 및 테스트 독립성
- 단점
- 성능 이슈
- UX 저하
- 보안/정책 제한
19.3 Js 프레임워크
- 보통은 JS 프레임워크에서 iframe 사용을 권장하진 앓지만 아래 조건에 부합하면 적당함
- 출처가 다르고 보안 격리가 필요
- 외부 위젯이나 광고처럼 iframe 방식만 지원
- 레거시 코드와의 통합이 필수
- 프레임워크로 자체 구현 비용이 iframe 대비 비효율적일 때
- 그 밖은 React의 Portal, Vue의 component, Angular의 NgModule 등을 활용한 컴포넌트 기반 아키텍처가 더 낫다고 하던데
- iframe을 JS 프레임워크에선 안 쓰는게 맞을 듯
19.4 최적화 전략
- 성능 최적화: 지연 로딩, 풀링, 캐싱, 크기 조정
- 보안 강화: sandbox, CSP, origin 검증, HTTPS 사용
💬 댓글