개발 slecs

광고 스크립트 경합 조건을 비동기 전환과 재시도 간격 조정으로 해결

목차

광고 로딩 경합 문제를 async 속성 하나 + retry 타이밍 조정으로 해결한 작업이다.

배경: 왜 광고 스크립트가 문제였나

Base.astro는 전체 레이아웃의 베이스 템플릿이다. 즉 여기서 로딩되는 스크립트는 모든 페이지에 영향을 준다. HawkEyesMaker.js 와 coupang g.js, 두 개의 서드파티 광고 스크립트가 이 파일에 동기 방식으로 박혀 있었고, 이게 페이지 초기 렌더 타이밍을 막고 있는 상황이었다.

문제의 핵심은 MobonSlot 쪽이었다. MobonSlot은 외부 광고 슬롯을 초기화하는 로직인데, 이 친구가 스크립트 로딩 순서에 민감하다. 위 두 스크립트가 동기로 로드되다 보니, 네트워크 지연이 조금만 생겨도 MobonSlot이 의존하는 전역 객체가 아직 준비 안 된 상태에서 초기화를 시도해버렸다. 결과는 슬롯 렌더 실패 또는 빈 광고 영역.

이런 류의 race condition은 서드파티 광고 스크립트에서 굉장히 자주 만나는 패턴이다. 광고 SDK들이 대부분 "자기가 먼저 떠야 한다"는 전제로 설계돼 있기 때문에, 여러 SDK가 섞이면 누가 먼저 뜨느냐에 따라 초기화 성공 여부가 갈린다.

변경 내용

항목 변경 전 변경 후
HawkEyesMaker.js 로딩 방식 동기 (<script src="...">) async 추가
coupang g.js 로딩 방식 동기 (<script src="...">) async 추가
MobonSlot retry 간격 (기존 값 또는 즉시 재시도) 6초로 조정

async 속성을 붙이면 HTML 파싱을 블록하지 않고 병렬로 스크립트를 내려받는다. 파싱 완료와 무관하게 다운로드 → 실행이 진행되므로, 메인 스레드가 레이아웃 렌더에 집중할 수 있게 된다.

<!-- before -->
<script src="https://example.cdn/HawkEyesMaker.js"></script>
<script src="https://partner.cdn/coupang/g.js"></script>

<!-- after -->
<script async src="https://example.cdn/HawkEyesMaker.js"></script>
<script async src="https://partner.cdn/coupang/g.js"></script>

MobonSlot retry를 6초로 설정한 건, async 스크립트 특성상 실행 타이밍이 보장되지 않기 때문이다. 너무 빠르게 재시도하면 아직 광고 SDK가 완전히 초기화되지 않은 시점을 계속 찌르게 되고, 이게 오히려 더 불안정한 동작을 만든다. 6초라는 값은 "대부분의 네트워크 환경에서 서드파티 스크립트가 충분히 내려받아질 시간"을 감안한 마진이다.

회고: async 하나인데 왜 이게 복잡하나

async 붙이는 건 한 글자 추가지만, 결과적으로 스크립트 실행 순서 보장이 사라진다는 트레이드오프가 생긴다. 이걸 모르고 그냥 async 달았다가 "SDK가 가끔 안 뜬다"는 버그 제보를 받으면 추적이 꽤 골치 아프다.

그래서 이번 작업에서 중요했던 건 retry 타이밍 조정이었다. async 전환 자체는 쉬운데, 그 이후 의존 관계를 어떻게 안전하게 처리할 것인지가 실질적인 난이도였다. MobonSlot이 광고 SDK 로드 완료 이벤트를 명시적으로 기다리는 구조가 아닌 이상, 충분한 대기 시간을 retry 간격으로 보장하는 게 현실적인 선택이다.

팀 입장에서도 이 변경은 좀 조심스러웠다. Base.astro는 전체 페이지 베이스니까, 여기서 뭔가 어긋나면 사이트 전반에 광고가 안 뜨는 상황이 된다. 광고 수익과 직결되는 파일이라 코드리뷰 때 "retry 6초 근거가 뭐냐"는 질문이 바로 나왔고, 그 자리에서 네트워크 지연 시나리오를 같이 짚었다.

서드파티 스크립트 성능 최적화는 항상 이 딜레마다. 빠르게 붙이면 race 나고, 느리게 붙이면 광고 노출 지표가 떨어진다. 이번엔 async로 메인 스레드 부담을 줄이면서 retry 마진으로 안정성을 챙긴 절충점을 선택했다.

다음 스텝이 있다면 MobonSlot 쪽 SDK 로드 완료 이벤트를 정확히 잡아서 retry 하드코딩을 없애는 방향이 맞겠지만, 그건 SDK 문서 깊이 파야 하는 다른 작업이다.


끝.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.