-
Web Streams 표준은 브라우저와 서버 간 일관된 데이터 스트리밍을 위해 설계되었지만, 현재는 복잡성과 성능 한계로 인해 개발자 경험이 저하되고 있음
- 기존 API는 락(lock) 관리, BYOB, 백프레셔(backpressure) 등 설계적 제약으로 인해 사용성과 구현 모두에서 불필요한 부담을 초래함
- Cloudflare는 비동기 반복(async iteration) 기반의 새로운 스트림 모델을 제안하며, 이 방식은 2배에서 최대 120배 빠른 성능을 보임
- 새 API는 단순한 async iterable 구조, 명시적 백프레셔 정책, 동기/비동기 병행 지원을 통해 효율성과 일관성을 높임
- 이 접근은 Node.js, Deno, Bun, 브라우저 등 모든 런타임에서 통합적 스트리밍 모델을 가능하게 하며, 향후 표준 논의의 출발점이 될 수 있음
Web Streams의 구조적 한계
- WHATWG Streams 표준은 2014~2016년에 개발되어 브라우저 중심으로 설계되었으며, 당시 async iteration이 존재하지 않아 별도의 reader/writer 모델을 도입함
- 이로 인해 락 관리, 복잡한 읽기 루프, BYOB 버퍼 처리 등 불필요한 절차가 생김
-
락(locking) 모델은 스트림을 독점적으로 점유해 병렬 소비를 막으며, releaseLock() 누락 시 스트림이 영구적으로 잠기는 문제가 발생함
-
BYOB(Bring Your Own Buffer) 기능은 메모리 재사용을 목표로 했지만, 복잡한 버퍼 분리·전송 모델로 인해 실제 활용도가 낮고 구현 난이도가 높음
-
백프레셔(backpressure) 는 이론상 지원되지만, desiredSize 값이 음수여도 enqueue()가 성공하는 등 실제 제어가 불가능한 구조임
- 각 read() 호출마다 Promise 생성이 강제되어, 고빈도 스트리밍에서는 성능 저하와 GC 부하를 유발함
실무에서 드러난 문제들
-
fetch() 응답 본문을 소비하지 않으면 연결 풀 고갈이 발생하며, tee() 사용 시 무제한 메모리 버퍼링이 생김
-
TransformStream은 읽기 준비 여부와 무관하게 즉시 처리되어, 느린 소비자 환경에서 버퍼 폭증을 초래함
- 서버사이드 렌더링(SSR)에서는 수천 개의 작은 청크 처리로 인한 GC 쓰레싱이 발생해 성능이 급감함
- 각 런타임(Node.js, Deno, Bun, Workers)은 이를 완화하기 위해 비표준 최적화 경로를 도입했으나, 이로 인해 호환성과 일관성 저하가 발생함
- Web Platform Tests는 70개 이상의 복잡한 테스트 파일을 요구하며, 이는 과도한 내부 상태 관리와 비직관적 동작의 결과임
새로운 스트림 API 설계 원칙
-
스트림은 단순한 async iterable로 정의되어, for await...of로 직접 소비 가능
-
Pull-through 변환을 채택해 소비자가 데이터를 요청할 때만 처리 수행
-
명시적 백프레셔 정책(strict, block, drop-oldest, drop-newest) 을 제공해 메모리 폭주 방지
-
배치 청크(Uint8Array[]) 단위로 데이터를 전달해 Promise 생성 비용을 줄임
-
바이트 단위 전용 처리로 단순화하며, BYOB나 복잡한 컨트롤러 개념 제거
-
동기(synchronous) 경로 지원으로 CPU 중심 작업에서 Promise 오버헤드를 제거
새로운 API의 예시와 특징
-
Stream.push()로 간단히 writer/readable 쌍 생성, Stream.text()로 전체 텍스트 수집 가능
-
Stream.pull()은 지연(lazy) 파이프라인을 구성해 소비 시점에만 실행
-
Stream.share()와 Stream.broadcast()는 명시적 다중 소비자 관리를 지원
-
Sync/Async 병행 API(Stream.pullSync(), Stream.textSync())로 I/O 없는 연산에서 성능 극대화
- Web Streams와의 상호 운용을 위해 간단한 어댑터 함수로 변환 가능
성능 비교 및 전망
- Node.js 기준 벤치마크에서 최대 80~90배, 브라우저에서는 최대 100배 이상 빠른 처리 속도 확인
- 예: 3단 변환 체인에서 275GB/s vs 3GB/s
- 성능 향상은 비동기 오버헤드 제거, 배치 처리, pull 기반 설계에서 기인
- 이 구현은 순수 TypeScript/JavaScript로 작성되었으며, 네이티브 구현 시 추가 향상 가능성 존재
- Cloudflare는 이 접근을 표준 논의의 출발점으로 제시하며, 개발자 커뮤니티의 피드백을 요청함
결론
- Web Streams는 당시 제약 속에서 합리적이었지만, 현대 JavaScript의 언어 기능과 개발 패턴에 부합하지 않음
- 새로운 async iterable 기반 모델은 단순성, 성능, 명시적 제어를 모두 충족하며, 런타임 간 일관된 스트리밍 생태계 구축 가능성 제시
- Cloudflare는 GitHub의 jasnell/new-streams에서 참조 구현과 문서, 예제 코드를 공개함
- 목표는 새로운 표준 제정이 아니라, “더 나은 스트림 API”를 논의하기 위한 실질적 출발점 마련임