본문 바로가기

JavaScript MutationObserver DOM 변경 감지 설정 파헤치기

@adepom2025. 12. 13. 11:52




MutationObserver란 무엇인가

웹 페이지의 DOM(Document Object Model)은 동적으로 변화하는 것이 일반적입니다. 새로운 콘텐츠가 로드되거나, 사용자의 상호작용에 따라 요소가 추가, 삭제, 수정될 수 있습니다. 이러한 DOM 변경 사항을 실시간으로 감지하고 싶을 때, JavaScript의 MutationObserver API를 활용할 수 있습니다. MutationObserver는 특정 DOM 서브트리에서 발생하는 변경을 비동기적으로 감시하는 인터페이스로, 변경 사항이 발생하면 콜백 함수를 실행합니다. 이는 기존의 DOM Mutation Events보다 더 효율적이고 유연한 DOM 변경 감지 방법을 제공합니다. 이를 통해 SPA(Single Page Application)의 상태 변화 감지, 동적 UI 업데이트, 특정 요소의 변화에 따른 부가 기능 트리거 등 다양한 상황에서 유용하게 사용할 수 있습니다. DOM 변경 감지를 위한 강력한 도구라고 할 수 있습니다.

 

특징 설명
비동기적 감시 DOM 변경 발생 시 즉시 콜백이 실행되는 것이 아니라, 브라우저가 적절한 시점에 콜백을 실행합니다. 이는 성능 저하를 방지합니다.
세밀한 설정 감시할 변경 유형(속성, 자식 노드 추가/삭제, 문자열 변경 등)과 대상 요소를 상세하게 지정할 수 있습니다.
성능 효율성 DOM Mutation Events와 비교했을 때, 변경 사항을 일괄적으로 처리하여 불필요한 콜백 호출을 줄여 성능 이점을 제공합니다.

JavaScript MutationObserver DOM 변경 감지 설정 파헤치기




MutationObserver 설정 방법

MutationObserver를 설정하는 과정은 크게 세 단계로 나눌 수 있습니다. 먼저, MutationObserver 인스턴스를 생성하고, 두 번째로 감시할 DOM 노드와 옵션을 지정하여 `observe()` 메서드를 호출합니다. 마지막으로 DOM 변경이 감지되었을 때 실행될 콜백 함수를 정의합니다. 옵션은 변경을 감지할 기준을 정의하는데, `childList`, `attributes`, `characterData` 등이 있으며, `subtree` 옵션을 통해 하위 노드까지 감시 범위를 확장할 수 있습니다. 또한 `attributeFilter`를 사용하여 특정 속성의 변경만 감지하도록 설정할 수도 있습니다. 이 과정을 통해 원하는 DOM 요소의 변경 사항을 정확하게 추적할 수 있습니다. 옵션 설정은 MutationObserver의 핵심적인 부분입니다.

 

▶ 1단계: `new MutationObserver(callback)`을 사용하여 MutationObserver 인스턴스 생성

▶ 2단계: `observer.observe(targetNode, config)`를 호출하여 DOM 노드 감시 시작. `targetNode`는 감시할 DOM 요소, `config`는 감시 옵션 객체.

▶ 3단계: `observer.disconnect()`를 호출하여 감시 중지

옵션 설명 값 (Boolean)
childList 자식 노드의 추가 또는 제거 감지 true/false
attributes 대상 노드의 속성 변경 감지 true/false
characterData 텍스트 노드의 내용 변경 감지 true/false
subtree 하위 트리(자식 노드들의 모든 자식 노드)의 변경 사항까지 감지 true/false




콜백 함수와 변경 기록 활용

MutationObserver의 핵심은 변경이 감지되었을 때 실행되는 콜백 함수입니다. 이 콜백 함수는 `MutationRecord` 객체의 배열을 인자로 받습니다. 각 `MutationRecord` 객체는 발생한 특정 변경 사항에 대한 상세 정보를 담고 있습니다. 예를 들어, `addedNodes` 속성은 새로 추가된 노드를, `removedNodes`는 제거된 노드를, `type` 속성은 변경의 종류(node, attributes, characterData)를 나타냅니다. 개발자는 이 `MutationRecord` 배열을 순회하며 필요한 로직을 수행할 수 있습니다. 변경 기록(MutationRecord)을 분석하여 DOM 변화에 대한 구체적인 조치를 취하는 것이 중요합니다. 예를 들어, 새로운 리스트 아이템이 추가되었을 때 특정 함수를 호출하거나, 속성이 변경되었을 때 UI를 업데이트하는 등의 처리를 할 수 있습니다.

 

핵심 포인트: MutationRecord 객체는 DOM 변경의 상세 정보를 제공하며, 이를 통해 개발자는 변경 사항에 대한 정밀한 제어가 가능합니다.

MutationRecord 속성 설명
type 변경 유형 (예: 'attributes', 'childList', 'characterData')
addedNodes 추가된 노드들의 NodeList
removedNodes 제거된 노드들의 NodeList
attributeName 변경이 발생한 속성의 이름 (type이 'attributes'일 때)
oldValue 변경 이전의 값 (attributes, characterData 타입에서 옵션으로 설정 가능)




MutationObserver의 다양한 설정 옵션

MutationObserver를 제대로 활용하기 위해서는 어떤 종류의 DOM 변경을 감지할지 세밀하게 설정하는 것이 중요합니다. 이를 위해 MutationObserver는 다양한 옵션을 제공합니다. 주요 옵션으로는 'childList', 'attributes', 'characterData', 'subtree' 등이 있으며, 이러한 옵션들을 조합하여 원하는 변경 사항만 선택적으로 감지할 수 있습니다. 예를 들어, 단순히 요소의 추가나 삭제만 감지하고 싶다면 'childList'만 'true'로 설정하고, 요소의 속성 변경을 감지하고 싶다면 'attributes'를 'true'로 설정하면 됩니다. 또한, 'subtree' 옵션을 'true'로 설정하면 해당 노드뿐만 아니라 모든 하위 노드의 변경 사항까지 감지 범위에 포함시킬 수 있습니다. 이러한 설정들을 어떻게 조합하느냐에 따라 MutationObserver의 성능과 정확도가 크게 달라질 수 있습니다.

각 옵션의 역할과 활용 방안을 명확히 이해하는 것이 DOM 변경 감지의 핵심입니다. 잘못된 설정은 불필요한 감지를 발생시켜 성능 저하를 일으킬 수 있으며, 반대로 필요한 변경을 놓치는 오류로 이어질 수도 있습니다. 따라서 프로젝트의 요구사항에 맞춰 최적의 설정을 구성하는 것이 필수적입니다.

 

옵션 설명 기본값
childList 자식 노드의 추가 또는 제거를 감지합니다. false
attributes 속성 변경을 감지합니다. (attributeOldValue, attributeFilter 옵션과 함께 사용될 수 있습니다.) false
characterData 텍스트 노드의 변경을 감지합니다. false
subtree 감시 대상 노드의 모든 하위 노드까지 감시할지 여부를 결정합니다. false




MutationObserver 콜백 함수의 이해

MutationObserver를 생성하고 설정을 마쳤다면, 실제 DOM 변경이 발생했을 때 호출될 콜백 함수를 정의해야 합니다. 이 콜백 함수는 'MutationRecord' 객체들의 배열을 인자로 받습니다. 각 'MutationRecord'는 단일 DOM 변경에 대한 정보를 담고 있습니다. 예를 들어, 'addedNodes' 속성은 새로 추가된 노드를, 'removedNodes' 속성은 제거된 노드를, 'attributeName' 속성은 변경된 속성의 이름을 담고 있습니다. 개발자는 이 'MutationRecord' 배열을 순회하며 각 변경 사항에 대한 필요한 로직을 수행하게 됩니다. 콜백 함수는 MutationObserver의 핵심적인 실행 지점으로, 변경된 DOM을 바탕으로 UI를 업데이트하거나, 데이터를 다시 가져오거나, 사용자 인터페이스를 동적으로 조작하는 등의 다양한 작업을 처리할 수 있습니다.

이 콜백 함수 내에서 효율적으로 DOM 변경을 처리하는 것이 중요합니다. 불필요한 DOM 조작을 최소화하고, 변경 사항에 대한 조건을 명확히 검사하여 필요한 로직만 실행해야 성능 저하를 방지할 수 있습니다. 또한, 여러 개의 변경 사항이 한 번에 발생할 경우 'MutationRecord' 배열을 효과적으로 관리하는 기법도 필요할 수 있습니다.

 

MutationRecord 주요 속성:
- addedNodes: 변경으로 인해 추가된 노드들의 NodeList
- removedNodes: 변경으로 인해 제거된 노드들의 NodeList
- type: 변경의 종류 ('attributes', 'childList', 'characterData')
- attributeName: 변경된 속성의 이름 (type이 'attributes'일 경우)




MutationObserver 사용 시 주의사항 및 성능 최적화

MutationObserver는 강력한 기능이지만, 잘못 사용하면 웹 애플리케이션의 성능에 부정적인 영향을 줄 수 있습니다. 가장 흔한 문제는 너무 광범위한 DOM 변경을 감지하도록 설정하거나, 콜백 함수 내에서 비효율적인 작업을 수행하는 경우입니다. 이를 방지하기 위해 첫째, 최소한의 필요한 옵션만 활성화하는 것이 중요합니다. 예를 들어, 자식 노드의 추가/삭제만 감지하면 된다면 'attributes'나 'characterData'는 비활성화하는 것이 좋습니다. 둘째, 콜백 함수는 최대한 빠르게 실행되어야 합니다. 무거운 연산이나 복잡한 DOM 조작은 콜백 함수 외부로 빼거나, 비동기 처리를 고려해야 합니다. 셋째, 필요 없는 관찰은 즉시 중지해야 합니다. MutationObserver 인스턴스의 .unobserve() 메소드를 사용하여 더 이상 DOM 변경 감지가 필요 없는 요소를 관찰 대상에서 해제함으로써 불필요한 오버헤드를 줄일 수 있습니다.

또한, `debounce` 또는 `throttle` 기법을 콜백 함수에 적용하여 변경이 연속적으로 발생할 때 콜백 함수가 과도하게 실행되는 것을 방지하는 것도 좋은 성능 최적화 방법 중 하나입니다. 이는 특히 자주 변경되는 동적인 UI 컴포넌트에서 유용합니다.

 

▶ 1단계: 필요한 최소한의 옵션으로 MutationObserver 설정

▶ 2단계: 콜백 함수 내에서 불필요한 연산을 최소화하고, 가능한 비동기 처리

▶ 3단계: 관찰이 끝난 요소는 `.unobserve()`를 호출하여 감시 중지

핵심 요약

• MutationObserver는 childList, attributes, characterData, subtree 등의 옵션으로 변경 감지 범위를 조절해야 합니다.
• 콜백 함수는 MutationRecord 배열을 통해 DOM 변경 정보를 전달받으며, 효율적인 처리가 중요합니다.
• 성능 저하를 방지하기 위해 필요한 옵션만 사용하고, 콜백 함수는 간결하게 유지하며, 불필요한 감시는 중지해야 합니다.




주요 질문 FAQ




Q. MutationObserver는 어떤 DOM 변경을 감지할 수 있나요?

MutationObserver는 DOM 트리의 거의 모든 변경 사항을 감지할 수 있습니다. 구체적으로는 다음과 같은 변경을 감지하는 데 사용됩니다.
- 자식 노드의 추가 또는 제거 (attributes, characterData, childList 옵션)
- 속성 값의 변경 (attributes 옵션)
- 텍스트 노드의 내용 변경 (characterData 옵션)
이러한 변경을 감지하기 위해 Observer 인스턴스를 생성할 때 'childList', 'attributes', 'characterData' 등의 옵션을 true로 설정할 수 있습니다.




Q. MutationObserver 설정 시 'attributes' 옵션만 사용해도 되나요?

네, 'attributes' 옵션만 사용하여 특정 요소의 속성 변경만을 감지할 수 있습니다. 예를 들어, 특정 요소에 'data-custom' 속성이 추가되거나 값이 변경될 때만 이를 감지하고 싶다면, MutationObserver를 생성할 때 `attributes: true`로 설정하고, `attributeFilter` 옵션을 사용하여 감지할 속성의 이름 목록을 지정할 수 있습니다. 이 경우, 자식 노드 변경이나 텍스트 내용 변경은 감지되지 않습니다.




Q. MutationObserver의 콜백 함수에서 변경된 DOM 노드 정보를 어떻게 가져오나요?

MutationObserver의 콜백 함수는 'MutationRecord' 객체의 배열을 인자로 받습니다. 각 MutationRecord 객체는 발생한 DOM 변경에 대한 상세 정보를 담고 있습니다. 예를 들어, 자식 노드가 추가 또는 제거된 경우 `addedNodes`와 `removedNodes` 속성을 통해 변경된 노드들을 확인할 수 있습니다. 속성이 변경된 경우에는 `attributeName`으로 변경된 속성 이름을, `oldValue`로 변경 전 속성 값을 얻을 수 있습니다.




Q. MutationObserver의 'subtree' 옵션은 무엇이며, 언제 사용해야 하나요?

'subtree' 옵션은 대상 요소의 모든 자손 요소에서 발생하는 변경 사항까지 감지하도록 설정하는 옵션입니다. 이 옵션을 `true`로 설정하면, 지정한 DOM 노드뿐만 아니라 그 하위에 있는 모든 노드의 변경까지도 MutationObserver가 감지하게 됩니다. 예를 들어, 특정 `div` 요소의 내용이 동적으로 계속 변경될 때, 해당 `div`뿐만 아니라 그 안의 여러 자식 요소들의 변경까지 모두 추적하고 싶을 때 유용하게 사용됩니다.




Q. MutationObserver 설정 시 'characterData' 옵션은 정확히 무엇을 감지하나요?

'characterData' 옵션은 텍스트 노드(Text Node)의 내용 변경을 감지합니다. 이는 HTML 요소 내부에 직접적으로 포함된 텍스트의 수정, 추가, 삭제 등을 의미합니다. 예를 들어, `

안녕하세요


` 라는 텍스트 노드의 내용이 `

안녕!


`으로 변경될 때, 'characterData' 옵션이 `true`로 설정되어 있다면 이 변경을 감지할 수 있습니다. 다만, HTML 태그 자체의 변경이나 속성 변경과는 별개로 순수 텍스트 노드의 내용 변화에 초점을 맞춘 옵션입니다.




Q. MutationObserver를 해제하려면 어떻게 해야 하나요?

MutationObserver를 더 이상 사용하지 않을 때는 명시적으로 해제하여 리소스를 관리하는 것이 좋습니다. Observer 인스턴스에 `disconnect()` 메서드를 호출하면 됩니다. 이 메서드는 해당 Observer가 관찰하고 있던 모든 DOM 변경 감지를 중지시킵니다. 만약 특정 노드에 대한 감지만 중지하고 싶다면, 해당 노드에 대해 `unobserve()` 메서드를 사용할 수도 있습니다.




Q. MutationObserver는 비동기적으로 작동하나요?

네, MutationObserver는 비동기적으로 작동합니다. DOM 변경이 발생하면 해당 변경 사항은 이벤트 루프의 이벤트 큐에 추가되고, 브라우저가 적절한 시점에 MutationObserver의 콜백 함수를 실행합니다. 즉, DOM 변경이 발생하는 즉시 콜백이 호출되는 것이 아니라, 현재 실행 중인 JavaScript 코드 블록이 완료된 후에 호출될 가능성이 높습니다. 이 비동기적인 특성은 UI 렌더링을 방해하지 않고 DOM 변경을 처리할 수 있도록 돕습니다.




Q. MutationObserver의 'childList' 옵션을 사용할 때, 'subtree' 옵션은 필수인가요?

아닙니다, 'childList' 옵션을 사용할 때 'subtree' 옵션이 필수는 아닙니다. 'childList' 옵션만 `true`로 설정하면, MutationObserver는 대상 요소의 바로 아래 레벨에 있는 자식 노드들의 추가 및 제거만 감지합니다. 만약 대상 요소의 모든 하위 노드(자손 노드)에서 발생하는 자식 노드의 추가 및 제거까지 모두 감지하고 싶다면, 그때 'subtree' 옵션을 `true`로 함께 설정해야 합니다. 이 두 옵션은 독립적으로 혹은 조합하여 사용할 수 있습니다.

adepom
@adepom

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차