
본편("미리보기와 렌더의 일치")에서 렌더 인프라를 관리형 서버리스로 택한 이야기를 했다. 옮기고 나니 새 제약이 생겼다. 서버리스 함수에는 실행 시간 제한이 있다.
10분 안에 끝나야 한다
관리형 렌더의 단일 실행에는 약 10분의 시간 제한이 있다. 짧은 영상이면 문제없지만, 긴 영상은 렌더 도중 제한에 걸려 통째로 실패할 수 있다. 성공하더라도 영상이 길어질수록 사용자의 대기 시간도 함께 늘어난다.
프레임을 나눠 병렬로 그렸다
그래서 한 영상을 통째로 렌더하지 않는다. 프레임을 수백 개 단위 청크로 나눠 여러 서버리스 함수가 병렬로 렌더하고, 끝나면 하나로 결합한다. 30fps 기준 30초 영상은 약 900프레임이고, 다섯 청크로 갈라져 동시에 처리된다. 진행률은 1초 간격 폴링으로 사용자에게 전달했다.
렌더를 병렬로 자를 수 있었던 건 본편의 결정 덕분이다. 렌더는 프레임 번호의 결정적 함수라서, 어느 함수가 몇 번 프레임을 그리든 결과가 같다. 흐르는 시계에 묶여 있었다면 청크로 자를 수 없었다.
얻은 것과 낸 비용
총 렌더 시간은 가장 느린 청크 하나 수준으로 줄었다. 900프레임을 순서대로 그리는 대신 180프레임씩 다섯 개가 동시에 돌기 때문이다. 단일 실행의 시간 제한도 자연히 피해 간다.
대신 비용이 있다. 청크를 나누고 결합하는 오버헤드가 붙고, 동시에 뜨는 함수만큼 실행 비용이 늘고, 결합 단계가 새로운 실패 지점이 된다.
정리
분할 렌더는 성능 최적화라기보다 제약 우회에 가깝다. 실행 시간 제한이라는 벽을 병렬성으로 돌아갔고, 그 병렬성은 렌더를 결정적 함수로 설계해 둔 데서 공짜로 얻었다. 인프라의 제약이 설계의 좋은 성질을 증명해 준 셈이다.
다음에 읽을 글

외부 API 응답은 왜 정규화 계층이 필요한가
외부 API의 응답 형태는 우리가 정하지 못한다. Content-Type을 진실로 삼아 응답을 세 갈래로 가르고, 봉투 네 종과 별칭 일곱 종을 하나의 스키마로 정규화하고, 상태코드는 사람이 행동할 수 있는 말로 번역했다. 통합의 품질은 어긋날 때 드러난다.

수십 MB WASM을 한 번만 받게 만들기
수십 MB WASM 엔진은 언제 받느냐와 몇 번 받느냐가 체감을 가른다. 변환이 필요한 순간에만 받고, 싱글톤과 Promise 공유로 동시 요청에도 다운로드는 한 번으로 막았다. 실패하면 공유 상태를 비워 다음 시도가 처음부터 다시 시작하게 했다.

브라우저 녹음은 되는데 음성합성 API는 왜 거절할까
브라우저는 WebM·48kHz·스테레오로 녹음하고, 음성합성 API는 WAV·16kHz·Mono·3MB 이하 입력을 요구한다. WebAssembly 트랜스코더를 브라우저에서 필요할 때만 로드해 형식을 맞추고, 보내기 전에 용량을 두 번 검사했다. 기술보다 중요했던 건 둘 사이를 잇는 통합 계층이었다.