[Open WebUI] JSON.parse(JSON.stringify()) 를 structuredClone으로 교체
PR 링크: open-webui/open-webui#22102 상태: Merged | 변경: +7 / -7
들어가며
Open WebUI의 Chat.svelte 컴포넌트에서 깊은 복사(deep clone)가 필요한 7곳에서 JSON.parse(JSON.stringify(obj)) 패턴을 사용하고 있었습니다. 이 패턴은 객체를 JSON 문자열로 직렬화했다가 다시 파싱하는 방식으로, 브라우저의 네이티브 structuredClone API 대비 약 2배 느립니다.
핵심 코드 분석
Before: JSON 직렬화/역직렬화
oldSelectedModelIds = JSON.parse(JSON.stringify(selectedModelIds));
const _files = JSON.parse(JSON.stringify(files));
_history = JSON.parse(JSON.stringify(_history));
JSON.stringify()는 객체를 문자열로 변환하고, JSON.parse()가 그 문자열을 다시 파싱하여 새 객체를 만듭니다. 이 과정에서:
- 문자열 할당 및 해제 비용 발생
- JSON 파싱 오버헤드 존재
undefined,Date,RegExp등의 타입이 올바르게 복사되지 않음
After: structuredClone API 사용
oldSelectedModelIds = structuredClone(selectedModelIds);
const _files = structuredClone(files);
_history = structuredClone(_history);
structuredClone은 브라우저의 네이티브 API로, 중간 문자열 생성 없이 직접 객체를 복사합니다.
왜 이게 좋은가
- 약 2배 빠른 성능: 중간 JSON 문자열 생성과 파싱 과정이 없어 더 빠릅니다.
- 정확한 타입 보존:
Date,ArrayBuffer,Map,Set등이 올바르게 복사됩니다. JSON 방식은 이들을 문자열이나 plain object로 변환합니다. - 가독성 향상:
structuredClone(obj)는 의도가 명확하고,JSON.parse(JSON.stringify(obj))보다 읽기 쉽습니다.
모든 변경이 cold path(모델 선택, 파일 준비, 히스토리 저장)에 있어 즉각적인 체감 성능 차이는 크지 않을 수 있지만, 현대적인 API 사용과 코드 품질 개선 관점에서 바람직한 변경입니다.
참고 자료
관련 포스트
- [Open WebUI] CodespanToken에서 JS 트랜지션을 CSS 애니메이션으로 교체하여 메인 스레드 부하 제거
- [Open WebUI] TTS 문장 파싱을 showCallOverlay 가드로 감싸 불필요한 O(n^2) 연산 제거
- [Open WebUI] CodeEditor에서 EditorView 미해제로 인한 메모리 누수 수정
- [Open WebUI] UserMessage에서 JSON 직렬화 대신 structuredClone과 빠른 경로 비교 적용
- [Open WebUI] 스트리밍 중 scrollToBottom을 rAF로 배치 처리하여 불필요한 리플로우 제거
PR Analysis 의 다른글
- 이전글 [Open WebUI] CodeBlock 토큰 비교 fast-path 최적화
- 현재글 : [Open WebUI] JSON.parse(JSON.stringify()) 를 structuredClone으로 교체
- 다음글 [Open WebUI] MultiResponseMessages에 O(1) Fast-path 비교 추가
댓글