광고 슬롯 조회를 빌드타임 정적 데이터로 전환해 런타임 DB 호출 제거
목차
런타임마다 DB를 찌르던 광고 슬롯 조회를 빌드타임 정적 데이터로 내려버린 작업이다.
왜 이 타이밍에 건드렸냐
MobonSlot 컴포넌트가 페이지 렌더링 시점에 매번 DB를 호출하는 구조였다. 광고 슬롯 단위(ad unit) 정보는 사실상 배포 주기 내에서 거의 바뀌지 않는 데이터인데, 요청마다 DB 커넥션을 열고 닫는 게 납득이 안 됐다. 팀 내에서 이미 money 패턴이라고 부르는 선례가 있었다 — 비슷한 성격의 준정적(quasi-static) 데이터를 빌드 스크립트로 긁어서 JSON 파일로 고정해두는 방식. 이번엔 그 패턴을 ads 도메인에 복제한 거다.
기술 부채라기보다 "언젠가 해야 했던 것"에 가까웠는데, 마침 MobonSlot 관련 이슈가 올라오면서 손댈 명분이 생겼다. 팀장 입장에서 이런 기회를 놓치면 또 몇 달 밀린다. 이슈 픽스 겸 구조 개선을 묶어서 처리했음.
변경 구조 한눈에
| 파일 | 역할 | 변경 방향 |
|---|---|---|
scripts/sync-ad-units.js |
빌드 전 DB → JSON 동기화 스크립트 | 신규 추가 |
src/data/ad-units.json |
슬롯 단위 정적 스냅샷 | 신규 생성 (빌드 결과물) |
src/components/MobonSlot.astro |
실제 슬롯 렌더 컴포넌트 | DB 호출 제거, JSON import로 교체 |
publish.sh |
배포 스크립트 | sync 스크립트 실행 단계 추가 |
package.json |
스크립트 등록 | sync-ad-units 커맨드 추가 |
핵심은 MobonSlot.astro 쪽이다. 기존엔 컴포넌트 내부에서 런타임 fetch/query가 있었을 텐데, 이제 그냥 JSON을 import해서 쓴다. Astro는 빌드타임에 정적 파일을 번들링하니까 이 흐름이 자연스럽게 맞아떨어진다.
// scripts/sync-ad-units.js 패턴 (개념 예시)
import { writeFileSync } from 'fs';
import { fetchAdUnits } from '../lib/db.js';
const units = await fetchAdUnits();
writeFileSync('src/data/ad-units.json', JSON.stringify(units, null, 2));
// MobonSlot.astro — 변경 후
import adUnits from '../data/ad-units.json';
const slot = adUnits.find(u => u.id === Astro.props.slotId);
런타임 의존성이 싹 사라진다. 컴포넌트 입장에서는 그냥 로컬 데이터를 읽는 것뿐.
publish.sh에 sync 단계를 끼워넣은 이유
여기서 잠깐 고민이 있었다. sync 스크립트를 CI에서 별도 job으로 뺄 수도 있고, 아니면 publish.sh 안에 순서대로 박아버릴 수도 있다. 후자를 택한 건 단순함 때문이다.
- 별도 CI job으로 분리하면 파이프라인 의존성 관리가 생긴다
publish.sh는 팀이 이미 배포 진입점으로 신뢰하고 있는 파일이다money패턴이 이미 같은 방식으로 작동하고 있어서, 팀원이 흐름을 파악하기 쉽다
일관성이 가독성이다. 두 개의 패턴이 같은 방식으로 동작하면, 세 번째 사람이 온보딩할 때 하나만 이해해도 나머지를 추론할 수 있다. 이게 팀 코드베이스에서 "패턴 복제"를 의식적으로 선택하는 이유다.
이런 구조 전환에서 항상 확인하는 것들
- 데이터 변경 주기: 슬롯 단위가 얼마나 자주 바뀌나? 배포보다 잦으면 이 패턴이 오히려 독이다
- stale 허용 범위: 광고 슬롯은 배포 사이클 내 stale이 허용되는가? 이번 케이스는 그렇다고 판단했다
- sync 실패 시 fallback: 스크립트가 죽으면 어떻게 되나? 기존 JSON이 남아있으니 빌드는 이전 스냅샷으로 진행된다 — 이건 장점이기도 하다
- 로컬 개발 환경: 개발자가
sync-ad-units를 실행하지 않으면 JSON이 없거나 낡아있다. 이 부분은 README나dev스크립트에 안내가 필요하다
마지막 항목은 코드리뷰 때도 지적했다 — package.json의 dev 스크립트에 sync를 prepend로 걸어두면 로컬에서 빠뜨리는 사고를 방지할 수 있다. 작은 거지만 팀원이 "왜 슬롯이 안 뜨지?"로 30분 날리는 걸 막는 게 낫다.
money 패턴이 이미 있었다는 게 이 작업을 빠르게 끝낼 수 있었던 핵심이었다. 좋은 패턴 하나가 코드베이스 전반의 속도를 올린다는 걸 다시 실감했음. 다음엔 비슷한 성격의 데이터가 더 있는지 훑어볼 생각이다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.