[Open WebUI] requestAnimationFrame으로 스트리밍 중 getContents() 디바운싱
PR 링크: open-webui/open-webui#22111 상태: Merged | 변경: +6 / -1
들어가며
getContents()는 메시지 트리를 순회하며 모든 어시스턴트 응답에서 코드/HTML/CSS/JS 블록을 정규식으로 스캔하는 함수입니다. Svelte의 반응성 구문 $: if (history)에 연결되어 있어 스트리밍 토큰이 들어올 때마다 실행되었습니다. 빠른 모델에서는 프레임당 수십 번 실행되지만, 브라우저는 60fps로만 렌더링하므로 시각적 이점 없이 CPU를 낭비하고 있었습니다.
핵심 코드 분석
Before (Chat.svelte):
$: if (history) {
getContents();
} else {
artifactContents.set([]);
}
After:
let contentsRAF = null;
$: if (history) {
cancelAnimationFrame(contentsRAF);
contentsRAF = requestAnimationFrame(() => {
getContents();
contentsRAF = null;
});
} else {
artifactContents.set([]);
}
왜 이게 좋은가
getContents()가 프레임당 최대 1회로 제한되어 CPU 사용량이 크게 감소합니다cancelAnimationFrame으로 이전 예약을 취소하므로 항상 최신 상태만 처리합니다- 같은 파일에서 이미
scrollRAF패턴으로 스크롤 디바운싱을 하고 있어 일관된 접근 방식입니다 - 아티팩트 미리보기는 여전히 실시간으로 업데이트됩니다 (1프레임 = ~16ms 지연은 체감 불가)
- 브라우저의 렌더링 주기와 연산 주기를 일치시키는 가장 자연스러운 최적화 방식입니다
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [Open WebUI] CodeEditor에서 EditorView 미해제로 인한 메모리 누수 수정
- 현재글 : [Open WebUI] requestAnimationFrame으로 스트리밍 중 getContents() 디바운싱
- 다음글 [Open WebUI] CodeBlock 토큰 비교 fast-path 최적화
댓글