티스토리 뷰

Electron API에서 off 메서드 구현의 중요성

Electron 애플리케이션 개발 과정에서 이벤트 리스너의 관리는 앱의 성능과 안정성을 결정짓는 중요한 요소입니다. 특히, preload에서 정의한 electronAPI를 통해 렌더러 프로세스에서 메인 프로세스로의 이벤트 송수신을 처리할 때, 메모리 누수를 방지하기 위해 리스너를 적절히 제거하는 것이 필수적입니다.

이 글에서는 off 메서드를 구현한 이유와 리스너에서 발생하는 메모리 누수의 원인, 그리고 useEffect를 하나의 장소에 모으는 이유에 대해 설명합니다.

off 메서드 구현의 이유

Electron에서 ipcRenderer를 사용하여 이벤트 리스너를 등록할 때, 이러한 리스너들은 특정 이벤트에 대해 반응하기 위해 메모리에 상주하게 됩니다. 컴포넌트가 언마운트되거나, 필요하지 않게 되었을 때 이들 리스너를 명시적으로 제거하지 않으면, 해당 컴포넌트가 사용하던 메모리가 계속해서 점유되어 있게 됩니다. 이는 애플리케이션의 메모리 사용량을 점진적으로 증가시키는 원인이 되며, 장시간 실행되는 앱에서는 성능 저하나 예기치 않은 동작의 원인이 될 수 있습니다. 따라서, off 메서드를 구현하여 이벤트 리스너를 적절히 제거함으로써 메모리 누수를 방지하고 앱의 성능을 유지할 수 있습니다.

off 메서드 구현의 중요성

Electron에서 이벤트 리스너를 관리하는 off 메서드의 구현은 메모리 누수를 방지하고 애플리케이션의 성능을 최적화하는 데 필수적입니다. 아래 코드는 preload.ts 파일에 electronAPI를 정의할 때 off 메서드를 추가하는 방법을 보여줍니다:

// preload.ts
import { contextBridge, ipcRenderer } from "electron";

export const electronAPI = {
  // 이벤트 리스너 등록
  on: (channel: string, callback: (…args: any[]) => void) => {
    const subscription = (_event: Electron.IpcRendererEvent, …args: any[]) =>
      callback(…args);
    ipcRenderer.on(channel, subscription);

    // 리스너 제거 함수 반환
    return () => {
      ipcRenderer.removeListener(channel, subscription);
    };
  },
  // 이벤트 리스너 제거
  off: (channel: string, callback: (…args: any[]) => void) => {
    ipcRenderer.removeListener(channel, callback);
  },
};

contextBridge.exposeInMainWorld("electronAPI", electronAPI);

리스너에서 발생하는 메모리 누수

이벤트 리스너에서 메모리 누수가 발생하는 주된 이유는, 이벤트 리스너가 등록된 후 적절히 제거되지 않아, 가비지 컬렉터에 의해 회수되지 않기 때문입니다. 특히, ⚙️ SPA(Single Page Application)에서는 사용자의 상호작용에 따라 동적으로 컴포넌트가 마운트되고 언마운트되는 과정이 반복됩니다. 이 과정에서 각 컴포넌트에 등록된 이벤트 리스너가 제거되지 않으면, 그 컴포넌트가 더 이상 사용되지 않더라도 메모리 상에 남아 있게 되어 점차 메모리 누수가 발생합니다.

아래 useEffect 코드는 리스너 등록과 함께 클린업 함수를 통해 리스너를 제거하는 방법을 보여줍니다:

// Clipboard 컴포넌트 내 useEffect 사용 예
useEffect(() => {
  const handleOCRrecognized = (text: string) => setResult(text);
  
  // 이벤트 리스너 등록 및 제거
  const ocrUnsubscribe = window.electronAPI.on(onOCRrecognized, handleOCRrecognized);

  // 컴포넌트 언마운트 시 리스너 제거
  return () => {
    ocrUnsubscribe();
  };
}, []);

Outro

결론적으로, Electron 애플리케이션에서 off 메서드를 구현하고, useEffect를 통해 이벤트 리스너의 등록과 제거를 관리하는 것은 애플리케이션의 성능을 최적화하고, 안정적인 운영을 보장하기 위한 중요한 패턴입니다. 이러한 방법을 통해 개발자는 메모리 누수 없이 효율적으로 리소스를 관리할 수 있습니다.

728x90