컴퓨터 사이언스/브라우저

[MutationObserver] DOM 변화를 감지하는 방법

Dachaes 2025. 4. 14. 14:26
728x90
반응형

MutationObserver 

현대 프론트엔드 프레임워크는 대부분 가상 DOM을 통해 효율적인 UI 업데이트를 제공합니다. 하지만 가상 DOM만으로는 감지할 수 없는 직접적인 DOM 변경도 존재합니다. 예를 들어,

  • 외부 라이브러리(jQuery, D3 등)가 DOM을 직접 조작할 때
  • 슬롯(slot)이나 iframe처럼 프레임워크 외부에서 변경이 일어날 때
  • 사용자 입력이나 비동기 처리로 DOM 구조가 바뀔 때

이럴 때 사용할 수 있는 도구가 바로 MutationObserver입니다.

이 글에서는 MutationObserver의 기본 개념부터 Vue, React에서 실전 적용하는 방법까지 자세히 다뤄보겠습니다.

 


1.  MutationObserver란?

MutationObserver는 브라우저가 제공하는 표준 Web API입니다. 지정한 DOM 요소에서 발생하는 변화를 감지해 콜백을 실행해 줍니다.

기본 구조

const observer = new MutationObserver(callback);
observer.observe(targetNode, options);
  • callback : DOM이 변경되었을 때 실행할 함수
  • targetNode : 감시할 DOM 요소
  • options : 어떤 변화를 감지할지 설정

감시 가능한 변화 종류

옵션 설명
childList 자식 노드 추가/삭제 감지
attributes 속성(attribute) 변경 감지
characterData 텍스트 노드 변경 감지
subtree 하위 모든 노드까지 감지 대상 포함

 


2.  실전 예제

a.  순수 JS로 MutationObserver 사용하기

<div id="app">
  <div id="content">초기 내용</div>
</div>

<script>
  const target = document.getElementById('content');

  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      console.log('변화 감지:', mutation);
    });
  });

  observer.observe(target, {
    childList: true,
    characterData: true,
    subtree: true,
  });

  // 테스트: 2초 후 내용 변경
  setTimeout(() => {
    target.textContent = '변경된 내용';
  }, 2000);
</script>

b.  Vue에서 MutationObserver 사용하기

Vue에서는 mounted, beforeUnmount 훅을 사용하여 MutationObserver를 설정하고 해제합니다.

<template>
  <div ref="watched">
    <slot />
  </div>
</template>

<script>
export default {
  mounted() {
    const target = this.$refs.watched;

    this.observer = new MutationObserver((mutations) => {
      console.log('Vue 감지됨:', mutations);
    });

    this.observer.observe(target, {
      childList: true,
      subtree: true,
    });
  },
  beforeUnmount() {
    this.observer.disconnect();
  },
};
</script>

c.  Composition API (Vue 3)

import { onMounted, onBeforeUnmount, ref } from 'vue';

export default {
  setup() {
    const el = ref(null);
    let observer = null;

    onMounted(() => {
      observer = new MutationObserver((mutations) => {
        console.log('Vue 3 감지됨:', mutations);
      });

      observer.observe(el.value, {
        childList: true,
        subtree: true,
      });
    });

    onBeforeUnmount(() => {
      observer && observer.disconnect();
    });

    return { el };
  },
};

d.  React에서 MutationObserver 사용하기

React는 함수형 컴포넌트와 훅(useEffect, useRef )을 이용해 MutationObserver를 설정합니다.

import React, { useEffect, useRef } from 'react';

function MutationWatcher({ onChange }) {
  const targetRef = useRef(null);

  useEffect(() => {
    const observer = new MutationObserver((mutations) => {
      console.log('React 감지됨:', mutations);
      onChange && onChange(mutations);
    });

    if (targetRef.current) {
      observer.observe(targetRef.current, {
        childList: true,
        subtree: true,
      });
    }

    return () => observer.disconnect();
  }, [onChange]);

  return (
    <div ref={targetRef}>
      {/* 감시 대상 DOM */}
    </div>
  );
}

export default MutationWatcher;

 


3.  어떤 경우에 MutationObserver를 써야 할까?

사용 상황 추천 여부 이유
외부 라이브러리로 DOM 변경 추천 React/Vue가 감지 못함
iframe 콘텐츠 감시 추천 외부 DOM 구조 변경
form 자동완성 감지 가능 일부 브라우저에서 유용
성능 민감한 페이지 주의 변경이 잦은 요소에 사용 시 성능 저하

 


4.  마무리

  • MutationObserver 는 React, Vue 등 어떤 프레임워크에서도 사용할 수 있는 범용 웹 API입니다.
  • Vue에서는 mounted/beforeUnmount 훅, React에서는 useEffect/useRef 로 연동합니다.
  • DOM이 프레임워크 외부에서 바뀌는 상황에서 매우 유용하며, 성능에도 주의해야 합니다.

함께 보면 좋은 자료

외부 사이트 :

 


728x90
반응형