토스는 어떻게 광고 속에 게임을 넣었을까
토스가 광고 시스템을 자체 구축하면서 서드파티 SDK 대신 국제 광고 표준 MRAID를 직접 구현해 플레이어블 광고(앱 설치 전 게임 체험)를 지원한 과정이다. mraid.js 브릿지, 5중 렌더링 완료 신호, 보안 중심 설계, 앱 심사 없는 즉시 배포를 동시에 달성했다.
요약 이어보기React로 만든 웹 게임에서 Safari의 HTMLMediaElement play() 재현 버그를 발견하고, Web Audio API로 근본적으로 해결하는 과정을 공유한다. 오디오 레이턴시와 크로스 브라우저 이슈까지 다루어 웹에서 효과음을 안정적으로 구현하려는 개발자에게 실용적인 해법을 제시한다.
핵심 포인트 - 문제 발견: Safari(맥/iOS)에서 audio.play() 두 번째 호출부터 재생 안 됨. Chrome은 정상. 아이패드 게임 플레이에 치명적 - audio.load() 우회법의 한계: sound.load() 후 sound.play()로 재생은 되지만 매번 네트워크 요청 발생. 잠재적 버그를 또 다른 버그로 막는 방식 - 레이턴시 문제: 키 입력 후 효과음 딜레이 — 게임 경험을 해치는 수준의 지연 발생 - Web Audio API 채택 이유: HTMLMediaElement의 Safari 버그와 레이턴시 없이 안정적으로 오디오 재생 가능. 버퍼 기반 재생으로 낮은 레이턴시 보장 - Web Audio API 핵심 흐름: AudioContext → fetch로 파일 로드 → decodeAudioData → AudioBufferSourceNode → connect(destination) → start() - 주의: AudioBufferSourceNode는 1회용 — 재생할 때마다 새 노드 생성 필요
상세 정리 - Safari의 currentTime=0 초기화 시도: 콘솔에선 0으로 표시되지만 play()는 동작 안 함. 사파리 HTMLMediaElement 버그로 추정 - audio.load() 해결책의 문제: 캐시로 커버되더라도 매 재생마다 네트워크 요청 발생. "버그를 버그로 막는" 방식이라 찜찜함 - AudioContext 생성: const ctx = new AudioContext(). 브라우저마다 vendor prefix 차이 주의(webkitAudioContext) - 오디오 파일 로드: fetch(url) → response.arrayBuffer() → ctx.decodeAudioData()로 AudioBuffer 획득 - 재생 코드: const source = ctx.createBufferSource(); source.buffer = audioBuffer; source.connect(ctx.destination); source.start(0) - 재생할 때마다 createBufferSource() 새로 호출 — 노드 재사용 불가 - Web Audio API 장점: 낮은 레이턴시(버퍼 직접 재생), 채널 수·재생 속도·피치 조절, 다중 오디오 믹싱 가능 - 게임 외 활용: 버튼 효과음, 알림음 등 웹에서 짧은 효과음 구현에 범용적으로 적용 가능 - iOS Safari 제약: 사용자 인터랙션(탭 등) 이전에 AudioContext 재생 불가 — 버튼 클릭 이벤트에서 시작해야 함
왜 읽나: Safari의 오디오 재생 버그를 Web Audio API로 근본 해결하는 과정과 AudioBufferSourceNode 기반 구현 패턴을 통해 크로스 브라우저 오디오 이슈 없는 웹 사운드 구현 방법을 익힐 수 있다.
토스가 광고 시스템을 자체 구축하면서 서드파티 SDK 대신 국제 광고 표준 MRAID를 직접 구현해 플레이어블 광고(앱 설치 전 게임 체험)를 지원한 과정이다. mraid.js 브릿지, 5중 렌더링 완료 신호, 보안 중심 설계, 앱 심사 없는 즉시 배포를 동시에 달성했다.
요약 이어보기채널톡 고객용 SDK에서 boot→shutdown→boot 연속 호출 시 사이드 이펙트가 중첩되는 타이밍 버그를 RxJS 기반 구조 개편으로 해결한 사례다. 비동기 흐름 직렬화에 RxJS, 동기적 상태 관리에 Zustand를 도입해 타이밍 비결정성을 구조 수준에서 제거했다.
요약 이어보기여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.
요약 이어보기