DOM & Virtual DOM

cojet·2022년 10월 26일
0
post-thumbnail

DOM(Document Object Model)

DOM은 문서 객체 모델로 HTML, XML 문서의 프로그래밍 인터페이스다. DOM은 문서의 구조화된 표현을 제공하고 프로그래밍 언어가 DOM구조에 접근할 수 있는 방법을 제공하여 문서의 구조, 스타일, 내용 등을 변경할 수 있게 한다.

현실에 있는 것을 특정 관점에서 보아 객체로 만드는 것을 추상화 또는 모델링 이라고 한다.
이러한 과정을 거쳐 만들어진 객체는 모델이라고 부른다.

DOM은 왜 탄생했을까요?

먼저 DOM은 JavaScript가 탄생하면서 같이 등장했다. 초창기에는 접근 가능한 태그도 많지 않았고 불편한 점도 많았지만 그에 따라 점차 발전하여 HTML 문서를 직접 수정까지 가능하게 되었다.

DOM Tree 구조

DOM트리의 시작점은 document로 문서 노드에 속한다.
문서 노드는 최상위 노드로 모든 노드에 접근하기 위해서는 문서 노드를 통해야한다.

요소 노드는 HTML태그 그 자체를 나타낸다. HTML 문서 구조를 그대로 표현한다고 할 수 있다.
또한 속성 노드, 텍스트 노드에 접근하려면 이 노드를 찾아야한다.

속성 노드요소 노드에 붙어있는 노드이고 태그에 정의되어 있는 속성을 나타낸다. 붙어있다고해서 자식 노드가 아님을 명심하자.

텍스트 노드는 요소의 텍스트를 표현하고 자식 노드를 가질 수 없다. -> DOM Tree의 단말 노드

DOM Tree의 렌더링

DOM Tree가 화면에 출력되는 과정을 알아보자

  1. 먼저 브라우저는 HTML을 읽고 파싱한 후 DOM Tree를 구성한다.
  2. Style Sheets를 파싱하여 Style Rules를 만들어 DOM 요소에 스타일을 입힌다.
    이 과정을 Attachment라고 한다.
  3. Layout을 통해 DOM 노드의 위치를 정해 Render Tree를 만든다.
    Render Tree가 완성되면 이 트리를 통해 실제 화면에 그린다.
  4. DOM 또는 Style이 수정되면 이 프로세스를 다시 반복한다.

DOM 다루기

<!DOCTYPE html>
<html>
  <head></head>

  <body>
    <div>
      <span class="span">Span1</span>
    </div>
    <div>
      <span class="span">Span2</span>
    </div>
    <ul>
      <li id="unique" class="list">list1</li>
      <li class="list">list2</li>
      <li class="list">list3</li>
    </ul>
    <p>Paragraph</p>
  </body>
</html>

DOM 선택

  1. getElementById
    DOM Tree에서 요소 노드를 id로 찾아 제일 먼저 찾은 요소 하나를 반환한다.

  2. getElementsByClassName
    DOM Tree에서 요소 노드를 class로 찾는다. 일치하는 모든 요소를 반환한다.

  3. getElementsByTagName
    DOM Tree에서 요소 노드를 태그 이름으로 찾는다. 일치하는 모든 요소를 반환한다.

  4. querySelector
    DOM Tree에서 요소 노드를 CSS Selector 문법으로 찾는다. 제일 먼저 찾은 요소 하나를 반환한다.

  5. querySelectorAll
    DOM Tree에서 요소 노드를 CSS Selector 문법으로 찾는다. 일치하는 모든 요소를 반환한다.

  6. window.[id]
    id가 있는 요소는 window 객체를 통해 찾을 수 있다. 여러개라면 리스트로 반환된다.

DOM 탐색

  1. parentNode
    선택한 요소 노드의 부모 노드를 불러온다. document는 최상위 노드이기 때문에 부모 노드는 null이다.

  2. firstElementNode
    선택한 요소 노드의 자식 요소 노드 중 첫 번째를 불러온다. 없을 경우 null을 반환한다. lastElementNode도 사용 가능하다.

  3. children
    선택한 요소 노드의 자식 요소 노드를 불러온다. 없을 경우 빈 배열을 반환한다.

  4. nextElementSibling
    선택한 요소 노드의 다음 형제 요소 노드를 불러온다. 없을 경우 null을 반환한다.

  5. previousElementSibling
    선택한 요소 노드의 이전 형제 요소 노드를 불러온다. 없을 경우 null을 반환한다.

DOM 조작

  1. class 접근
    선택한 요소 노드에서 className과 classList로 요소의 class 속성을 불러오고 변경할 수 있다.

  2. hasAttribute
    선택한 요소 노드에서 속성을 가지는지 확인 가능하다.

  3. getAttribute
    선택한 요소 노드에서 속성 값을 반환한다. 없다면 null을 반환한다.

  4. setAttribute
    선택한 요소 노드에서 속성을 정의한다.

  5. removeAttribute
    선택한 요소 노드에서 속성을 제거한다.

  6. textContent
    선택한 요소 노드에서 텍스트 노드에 접근하여 변경할 수 있다.

  7. innerHTML
    선택한 요소 노드 내부 HTML을 수정한다. XSS위험이 있다.

    XSS(Cross Site Scripting)
    웹 해킹 공격 중 하나로 게시판이나 웹 메일 등에 스크립트 코드를 삽입해 개발자가 구현하지 않은 기능이 작동하게 하는 치명적일 수 있는 공격이다.

  8. createElement
    요소 노드를 생성할 수 있다.

  9. appendChild
    선택한 요소 노드 마지막 자식 요소로 추가한다.

  10. removeChild
    선택한 요소 노드 자식 노드 중 해당하는 요소를 제거한다.

Virtual DOM

만약 여러개의 DOM 객체를 수정한다면 어떤 일이 발생할까?
예를 들어 100개의 DOM을 수정하면 최악의 경우 100번의 레이아웃과 렌더링을 하게된다.

이러한 경우 Virtual DOM을 사용한다. 개발자가 코드를 하나하나 최적화 하는것은 쉽지 않고 대규모 어플리케이션의 경우 더욱 그렇다. virtual DOM은 실제DOM Tree를 자바스크립트 객체로 만든것으로 필요한 정보만 담아 만들어진다.
EventDOM 이 수정되는 짧은 순간에 DOM을 직접 수정하지 않고 virtual DOM을 바뀐 부분만 수정한후 렌더링하면 브라우저 렌더링 프로세스가 줄어든다.

우리가 주로 사용하는 React.js, Vue.jsvirtual DOM을 사용하고있다.

Virtual DOM은 DOM보다 빠른가?

React 핵심 개발자에 따르면 React는 DOM보다 빠르다는 것은 미신일 뿐이고 유지보수에 용이한 애플리케이션을 만들도록 도와주고 대부분의 유스케이스에 충분히 빠를 뿐이라고 언급했다.

이는 페이지에 그려지는 DOM이 많을수록 느려지는 것은 같다는 뜻이다. 왜냐하면 (virtual DOM, DOM) 이 두가지를 탐색 해야하기 때문이다.

브라우저 렌더링 횟수를 줄여줄뿐 실제로는 더 느림
메모리도 그 만큼 더 사용하게 된다.

하지만, 일반적인 웹사이트에서 그정도의 성능 저하가 문제되는 경우는 드물고 빠른 개발을 위해 성능 최적화보다 개발 편의성이 더 중요할때가 많다. 그래서 virtual DOM을 많이 사용한다.

0개의 댓글