시작은 React reconciliation, 그 전에는 React18에 적용된 Suspense, useTransition 등에 대한 궁금증에서부터였다. 관련 글을 읽다보니 자주 나오는 개념인 DOM node, element 등에 대한 이해도를 높이고자 정리하는 글
Document Object Model, DOM, 은 HTML 혹은 XML 문서를 각 노드가 문서의 객체인 트리 구조로서 처리하기 위한 interface이다. DOM은 tree를 query (불러오기), 구조와 스타일을 변경하기 위한 여러 메소드들을 제공하기도 한다.
DOM은 또한 element라는 단어를 사용한다: node와 상당히 비슷하다. 그럼 두개는 무엇이 다른지 알아보자
node와 element의 차이를 알아보기 위해서 node가 무엇인지 알아보는게 중요하다.
더 큰 관점에서 보면 DOM document는 노드 계층으로 구성된다. 각 노드는 부모와 자식 혹은 각각 가질 수 있다. 다음 HTML 문서를 살펴보자
<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <!-- Page Body -->
    <h2>My Page</h2>
    <p id="content">Thank you for visiting my web page!</p>
  </body>
</html>
위 html은 다음과 같은 계층으로 표현이 가능하다.
ㄴ DOCTYPE: html
ㄴ HTML
	ㄴHEAD
    	ㄴTITLE
        	ㄴ#text: My Page
	ㄴBODY
    	ㄴ#comment: Page Body
        ㄴH2
        	ㄴtext: My Page
        ㄴP id="content"
        	ㄴ#text: Thank you for visiting my web page!
<html> 은 <head> and <body> node들을 자식으로 가지고 있는 document tree의 node이다. 
<body> 또한 세개의 자식을 갖는 노드다. <!-- Page Body -->, heading <h2>, 그리고 paragraph <p>. <body> node의 부모는 <html> node다.
HTML document의 tag들은 노드를 대표한다. 더 흥미로운건 text 또한 노드이다. paragraph node <p> 는 text node "Thank you for visiting my web page!"를 자식으로 갖는다.
DOM Node 인터페이스를 살펴보면 Node.nodeType 속성으로 노드의 타입을 구분할 수 있다.
Node.nodeType는 노드의 타입을 나타내는 다음의 값들이 있다.
Node.ELEMENT_NODENode.ATTRIBUTE_NODENode.TEXT_NODENode.CDATA_SECTION_NODENode.PROCESSING_INSTRUCTION_NODENode.COMMENT_NODENode.DOCUMENT_NODENode.DOCUMENT_TYPE_NODENode.DOCUMENT_FRAGMENT_NODENode.NOTATION_NODE위 상수들은 노드 유형을 의미 있게 나타낸다: 예를 들면, Node.ELEMENT_NODE은 element node를 나타낸다. 
예를 들어, paragraph node를 선택하고 선택된 노드의 타입을 살펴보자
const paragraph = document.querySelector('p');
paragraph.nodeType === Node.ELEMENT_NODE; // => true
예상대로 paragraph.nodeType은 paragraph가 element인 것을 알 수 있듯, Node.ELEMENT_NODE값을 가지고 있다. 
paragraph는 또한 text node를 가지고 있다.
const paragraph = document.querySelector('p');
const firstChild = paragraph.childNodes[0];
firstChild.nodeType === Node.TEXT_NODE; // => true
또한 노드 타입에는 노드의 전체 document tree를 나타내는 Node.DOCUMENT_NODE 타입이 있다.
document.nodeType === Node.DOCUMENT_NODE; // => true
DOM Node가 무엇인지 잘 파악했으니 element와 구분점을 알아보자.
node에 대해 이해가 높다면 답은 명확하다: element은 Node.ELEMENT_NODE 라는 특정 타입의 노드이다. 
간단하게 element는 HTML의 tag를 사용해 작성된 node라고 볼 수 있다. <html>, <head>, <title>, <body>, <h2> 등 모두 tag로 대변될 수 있기 때문에 element이다.
하지만 document type, comment, text 노드는 모두 tag로 작성되지 않았기 때문에 element가 아니다.
Node는 node의 constructor이고 HTMLElement는 Javascript DOM에서 element의 constructor이다. paragraph은 node이면서 element이기에 Node와 HTMLElement의 instance다.
const paragraph = document.querySelector('p');
paragraph instanceof Node;        // => true
paragraph instanceof HTMLElement; // => true
element는 node의 subtype으로도 볼 수 있다: 고양이(element)와 동물(node)의 관계
node와 element의 구분을 차치하고, 오직 node 혹은 오직 element를 위한 DOM 속성들을 구분해볼 필요가 있다.
다음 Node 타입의 속성은 Node 혹은 NodeList로 평가된다.
node.parentNode; // Node or null
node.firstChild; // Node or null
node.lastChild;  // Node or null
node.childNodes; // NodeList
하지만 다음 속성들은 element 혹은 element collection(HTMLCollection)이다.
node.parentElement; // HTMLElement or null
node.children;      // HTMLCollection
node.childNodes와 node.children 모두 children list를 반환하는데 왜 구분이 되어 있을까? 다음 예제 코드로 살펴보자
<p>
  <b>Thank you</b> for visiting my web page!
</p>
 그 후 paragraph의 childNodes와 children을 살펴보면,
const paragraph = document.querySelector('p');
paragraph.childNodes; // NodeList:       [HTMLElement, Text]
paragraph.children;   // HTMLCollection: [HTMLElement]
paragraph.childNodes collection은 2개의 노드를 갖는다: bold element인 <b>Thank you</b>와 text node인 for visiting my web page!
하지만 paragraph.children collection은 bold element인 <b>Thank you</b>만 가지고있다. paragraph.children은 오직 element만 가지고 있을 수 있기 때문에 타입이 element(Node.ELEMENT_NODE)가 아닌 text 타입(Node.TEXT_NODE)를 갖는 text node는 포함되지 않는다. 
DOM document는 노드 의 계층적 collection이다. 각 node는 부모, 자식 혹은 둘다 가질 수 있다.
즉 HTML의 계층을 표현할 수 있는 모든것은 다 Node다.
element은 Node.ELEMENT_NODE 라는 특정 타입의 노드로 HTML 문서의 tag를 사용해 작성된 node다.
Node는 element를 포함한다: 동물(Node)과 고양이(element)의 관계. 또한 Node이면서 element인 경우도 있다: paragraph.
다만, Document node (Node.DOCUMENT_NODE)은 절대 부모를 가질 수 없다.