웹 개발에서 DOM(Document Object Model)은 HTML 문서를 자바스크립트로 제어할 수 있게 해주는 핵심 개념입니다. DOM은 문서를 트리 형태의 노드 구조로 표현하며, 여기서 중요한 개념이 바로 Node와 Element입니다. 많은 개발자들이 이 둘을 같은 의미로 사용하거나 헷갈려 하지만, 정확히 구분하면 코드의 안정성과 효율성을 높일 수 있으며, React 같은 라이브러리를 이해할 때도 큰 도움이 됩니다. 이 글에서는 Node와 Element의 개념적 차이부터 Vanilla JS에서의 DOM 탐색, 그리고 React로 이어지는 추상화 구조까지 자세히 정리합니다.
Node와 Element란 무엇인가?
Node는 DOM 트리의 모든 구성 요소를 지칭하는 가장 일반적인 단위입니다. HTML 문서의 각 부분(태그, 텍스트, 주석 등)은 모두 노드로 표현됩니다. 반면 Element는 <div>
, <p>
등 실제 HTML 태그 요소에 해당하는 노드의 한 종류입니다.
1. Node의 종류
DOM에서 정의하는 노드 유형은 다음과 같습니다:
- Element Node (1): HTML 요소
- Text Node (3): 태그 사이의 텍스트
- Comment Node (8): 주석
- Document Node (9): 전체 문서
- DocumentFragment Node (11): 문서 조각
2. Element란?
Element
는 Node
를 상속한 DOM 인터페이스이며, 태그 기반 구조만 포함합니다. 즉, 모든 Element는 Node이지만, 모든 Node가 Element는 아닙니다.
console.log(document.body.nodeType); // 1
console.log(document.createTextNode('hello').nodeType); // 3
3. 핵심 구분 요약
특성 | Node | Element |
---|---|---|
범위 | 모든 DOM 구조 포함 | HTML 요소만 해당 |
nodeType | 1, 3, 8 등 다양 | 항상 1 |
인터페이스 | Node | Element extends Node |
예시 | <div>, 텍스트, 주석 | <div>, <p> 등 태그 |
Vanilla JS에서의 Node vs Element 처리
Vanilla JS에서는 Node와 Element의 차이를 명확히 이해하지 않으면 DOM 탐색 시 불필요한 오류나 성능 저하를 유발할 수 있습니다.
1. DOM 탐색 관련 차이
childNodes
: 모든 Node 반환 (텍스트 노드 포함)children
: Element만 반환firstChild
vsfirstElementChild
const list = document.getElementById('myList');
console.log(list.childNodes); // 텍스트 포함 모든 노드
console.log(list.children); // 실제 <li> 같은 요소만
console.log(list.firstChild); // text node (줄바꿈 포함 가능)
console.log(list.firstElementChild); // 실제 요소 노드
2. 노드 탐색 중 발생할 수 있는 오류
아래와 같은 경우 실수하기 쉽습니다:
list.childNodes.forEach(node => {
node.classList.add('item'); // text node에는 classList가 없어 오류 발생
});
해결: 반드시 nodeType === 1
체크 또는 children
사용
3. DOM 조작과 성능
Node를 다룰 때는 불필요한 텍스트 노드 반복, 주석 처리 등을 피하기 위해 Element 기준 접근을 권장합니다. 특히 DOM 트리 재조작 시 Element 기반 탐색이 성능상 더 안정적입니다.
React에서의 DOM 구조와 Element의 의미
React에서는 실질적인 DOM 대신 Virtual DOM과 React Element라는 개념이 등장합니다.
1. JSX → React.createElement
const element = <div className="box">Hello</div>;
const reactElement = React.createElement('div', { className: 'box' }, 'Hello');
React Element는 실제 DOM이 아니라, JS 객체 형태의 선언 구조입니다. 즉, 우리가 JSX로 작성하는 구조는 렌더링 시점까지는 DOM과는 별개입니다.
2. Virtual DOM 구조
React는 브라우저의 실제 DOM(Node/Element)을 직접 조작하지 않고, 메모리 상의 Virtual DOM을 구성해 이전 구조와 비교(diff) 후 변경된 부분만 갱신합니다.
3. Fiber 구조
React 16 이후 등장한 Fiber는 Virtual DOM보다 더 세밀한 작업 단위입니다. Fiber 역시 노드 기반 트리를 구성하며, 작업 우선순위/비동기 렌더링 등의 정보를 담습니다.
4. React에서의 Element
- React Element ≠ DOM Element
- React Element는 단순한 JS 객체
- 렌더링 후에야 실제 DOM(Element Node)로 바뀜
따라서 다음과 같은 코드에서 DOM 요소를 직접 참조하려면 ref
를 사용해야 합니다:
const ref = useRef();
useEffect(() => {
ref.current.focus(); // 실제 DOM Element
});
실무에서의 차이점 인식과 면접 대응 전략
1. 실전 코드에서 구분해야 하는 이유
- Node는 예기치 않은 타입이 섞일 수 있어 오류 발생 위험
- Element만 조작해야 할 때는
children
사용 필수 - DOM 반복/순회 최적화 시 nodeType 체크가 성능에 영향
2. 면접 질문 예시
- “Node와 Element의 차이는?”
- “childNodes와 children의 차이를 아시나요?”
- “React의 Element는 실제 DOM인가요?”
3. 모범 답변 팁
“Node는 DOM의 모든 노드를 포괄하는 개념이고, Element는 HTML 요소에 해당하는 Node의 하위 개념입니다. childNodes는 텍스트 노드까지 포함하지만, children은 Element만 포함하므로 구조적으로 구분할 필요가 있습니다. React의 Element는 DOM이 아닌 가상 구조이며, 렌더링 이후에만 실제 DOM이 생성됩니다.”
결론
Node와 Element는 HTML 문서 구조를 이해하고, DOM을 효율적으로 제어하기 위해 반드시 구분해야 할 개념입니다. Vanilla JS 환경에서는 불필요한 노드 접근을 피하고 정확한 탐색을 위해 Element 중심으로 처리하는 것이 안정적입니다. React에서는 Element가 추상화된 JS 객체이므로 DOM과는 전혀 다른 계층에서 작동한다는 점도 반드시 인식해야 합니다.
이러한 차이를 명확히 이해하고, 상황에 맞게 접근 방식을 바꿀 수 있다면 DOM 조작 실수는 물론, 렌더링 최적화와 성능 개선에도 도움이 됩니다. 그리고 이는 실무와 면접 모두에서 당신의 역량을 증명하는 중요한 기준이 됩니다.