본문으로 건너뛰기

[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로, 중간 문자열 생성 없이 직접 객체를 복사합니다.

왜 이게 좋은가

  1. 약 2배 빠른 성능: 중간 JSON 문자열 생성과 파싱 과정이 없어 더 빠릅니다.
  2. 정확한 타입 보존: Date, ArrayBuffer, Map, Set 등이 올바르게 복사됩니다. JSON 방식은 이들을 문자열이나 plain object로 변환합니다.
  3. 가독성 향상: structuredClone(obj)는 의도가 명확하고, JSON.parse(JSON.stringify(obj)) 보다 읽기 쉽습니다.

모든 변경이 cold path(모델 선택, 파일 준비, 히스토리 저장)에 있어 즉각적인 체감 성능 차이는 크지 않을 수 있지만, 현대적인 API 사용과 코드 품질 개선 관점에서 바람직한 변경입니다.

참고 자료

댓글

관련 포스트

PR Analysis 의 다른글