[Open WebUI] UserMessage에서 JSON 직렬화 대신 structuredClone과 빠른 경로 비교 적용
PR 링크: open-webui/open-webui#22098 상태: Merged | 변경: +8 / -3
들어가며
Svelte의 반응형 시스템에서 객체 변경 감지는 성능에 직접적인 영향을 미친다. Open WebUI의 UserMessage 컴포넌트는 히스토리에서 메시지 객체를 복사하고, 변경 여부를 JSON.stringify 비교로 판단한 후 재복사하는 패턴을 사용하고 있었다. 이 과정에서 JSON.parse(JSON.stringify()) 깊은 복사와 매 반응형 업데이트마다 전체 객체 직렬화가 발생했다.
핵심 코드 분석
Before: JSON 직렬화 기반 복사와 비교
let message = JSON.parse(JSON.stringify(history.messages[messageId]));
$: if (history.messages) {
if (JSON.stringify(message) !== JSON.stringify(history.messages[messageId])) {
message = JSON.parse(JSON.stringify(history.messages[messageId]));
}
}
After: structuredClone + O(1) 빠른 경로
let message = structuredClone(history.messages[messageId]);
$: if (history.messages) {
const source = history.messages[messageId];
if (source) {
if (message.content !== source.content) {
message = structuredClone(source);
} else if (JSON.stringify(message) !== JSON.stringify(source)) {
message = structuredClone(source);
}
}
}
왜 이게 좋은가
- structuredClone 사용:
JSON.parse(JSON.stringify())는undefined,Date,RegExp등을 올바르게 처리하지 못한다.structuredClone은 브라우저 네이티브 API로 더 정확하고 빠른 깊은 복사를 제공한다. - O(1) 빠른 경로 비교: 대부분의 메시지 변경은
content필드 변경이다. 문자열 비교는 O(n)이지만, 전체 객체를 JSON으로 직렬화하는 것보다 훨씬 가볍다. content가 같을 때만 전체 비교로 폴백한다. - null 안전성:
source존재 여부를 먼저 확인하여 삭제된 메시지에 대한 에러를 방지한다.
채팅 중 history.messages가 변경될 때마다 이 비교가 실행되므로, 빠른 경로로 대부분의 불필요한 직렬화를 건너뛸 수 있다.
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [Open WebUI] 이벤트 이미터에서 DB 호출 비동기화, 중간 상태 저장 제거, elif 체인 적용
- 현재글 : [Open WebUI] UserMessage에서 JSON 직렬화 대신 structuredClone과 빠른 경로 비교 적용
- 다음글 [Open WebUI] CodeEditor에서 EditorView 미해제로 인한 메모리 누수 수정
댓글