[Open WebUI] Notes.svelte 메모리 누수 수정
PR #21963 - fix: fix memory leaking of Notes.svelte
들어가며
Open WebUI의 Notes.svelte 컴포넌트에서도 ChatControls와 동일한 패턴의 메모리 누수가 발견되었습니다. onMount가 비동기 함수(async)로 선언되어 있고, onDestroy에서 동기적으로 이벤트 리스너를 해제하고 있었습니다. 비동기 onMount가 완료되기 전에 onDestroy가 호출되면, 이벤트 리스너가 해제되지 않는 문제가 발생했습니다.
핵심 코드 분석
Before
onMount(async () => {
// 동기적 초기화
dropzoneElement?.addEventListener('dragover', onDragOver);
dropzoneElement?.addEventListener('drop', onDrop);
dropzoneElement?.addEventListener('dragleave', onDragLeave);
});
onDestroy(() => {
clearTimeout(searchDebounceTimer);
const dropzoneElement = document.getElementById('notes-container');
if (dropzoneElement) {
dropzoneElement?.removeEventListener('dragover', onDragOver);
dropzoneElement?.removeEventListener('drop', onDrop);
dropzoneElement?.removeEventListener('dragleave', onDragLeave);
}
});
After
onMount(() => {
// 동기적 초기화
dropzoneElement?.addEventListener('dragover', onDragOver);
dropzoneElement?.addEventListener('drop', onDrop);
dropzoneElement?.addEventListener('dragleave', onDragLeave);
return () => {
clearTimeout(searchDebounceTimer);
if (dropzoneElement) {
dropzoneElement?.removeEventListener('dragover', onDragOver);
dropzoneElement?.removeEventListener('drop', onDrop);
dropzoneElement?.removeEventListener('dragleave', onDragLeave);
}
};
});
왜 이게 좋은가
- async 제거:
onMount에서 불필요한async선언을 제거하여, Svelte가 반환된 정리 함수를 올바르게 인식합니다. (async 함수는 Promise를 반환하므로 Svelte가 정리 함수로 처리하지 않습니다.) - 같은 DOM 참조 보장:
onDestroy에서document.getElementById로 새로 요소를 찾는 대신,onMount클로저 내의 동일한dropzoneElement참조를 사용합니다. - 불필요한 console.log 제거:
onDestroy에 있던 디버깅용console.log('destroy')도 함께 정리되었습니다. - 경쟁 조건 해소:
onMount반환값으로 정리 로직을 제공하면, Svelte 프레임워크가 마운트/언마운트 순서를 올바르게 관리합니다.
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [Open WebUI] 모델 생성 페이지 메모리 누수 수정: 이벤트 리스너 해제
- 현재글 : [Open WebUI] Notes.svelte 메모리 누수 수정
- 다음글 [Open WebUI] 스트리밍 중 메시지 리스트 재구성을 프레임당 1회로 제한
댓글