DOM&BOM

작성일

DOM

  • 문서에 대한 모든 내용을 담고 있는 객체
  • 텍스트 파일로 만들어진 문서를 브라우저가 이해할 수 있는 구조로 구성한 것
  • HTML 요소 간의 부자 관계를 반영하여 모든 노드들을 트리 구조로 구성한 것
  • HTML, XML 문서의 프로그래밍 interface
  • 문서의 구조화된 표현을 제공하며 프로그래밍언어가 DOM구조에 접근할 수 있는 방법을 제공하여 문서 구조, 스타일, 내용등을 변경할 수 있게 도움

image

image html 문서를 구성하는 개별적인 요소를 의미한다. html 요소는 렌더링엔진에 의해 파싱되어 DOM을 구성하는 유선 노드 객체로
변환된다.

image
이때 html의 요소의 Attribute는 Attribute 노드로 텍스트 컨텐츠는 텍스트 노드로 변환된다.
image
이런 html 요소들이 들어있는 html 문서를 렌더링엔진이 파싱하여 다음과 같이 노드 객체로 구성된 트리 구조를 가진 DOM을
생성한다. 이처럼 DOM은 노드 객체의 계층적인 구조로 구성된다. 노드 객체는 각각 종류가 있으며, 상속 구조를 갖는다.
노드 객체는 총 12가지가 있지만, 제일 중요한 4가지에 대해 알아보자.

문서 노드

  • DOM 트리의 최상위에 존재하는 루트 노드로서 documnet 객체를 가르킨다.
  • HTML 문서당 document 객체는 유일하다.
  • DOM 트리의 루트 노드이므로 DOM 트리의 노드를 접근하기 위한 진입점 역학을 한다.
  • 즉, 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다.

요소 노드

  • HMTL 요소를 가리키는 객체다.
  • HTML 요소 간의 중첩에 의해 부자관계를 가지며, 이 부자관계를 통해 정보를 구조화한다.
  • 즉, 요소 노드는 문서의 구조를 표현한다.

어트리뷰트 노드

  • HTML 요소의 어트리뷰트를 가르키는 객체다.
  • 어트리뷰트 노드는 지정된 HTML 요소의 요소 노드와 형제 관계를 갖는다.
  • 어트리뷰트 노드에 접근하여 어트리뷰트를 참조하거나 변경하려면 먼저 형제 노드인 요소 노드에 접근해야한다.

텍스트 노드

  • HTML 요소의 텍스트를 가리키는 객체다.
  • 문서의 정보를 표현한다.
  • 텍스트 노드는 요소 노드의 자식 노드이며, 자식 노드를 가질 수 없는 리프 노드이다.
  • 텍스트 노드에 접근하려면 먼저 부모 노드인 요소 노드에 접근해야 한다.

image
노드 객체도 자바스크립트 객체 힘으로 프로토 타입에 의한 상수 구조를 갖는다. 모든 노드 객체는 오브젝트, 이벤트 타겟,
노드 인터페이스를 상속 받는다.
여기서 이벤트 타겟은 이벤트와 관련된 예를 들어 addEventListener와 removeEventListener와 같은 기능을 제공한다.

렌더링 과정

image
브라우저의 랜더링 엔진은 클라이언트가 서버로부터 요청한 html부터 순차적으로 파싱하여 DOM을 생성해 나간다.
이때, 렌더링 엔진은 DOM을 생성해 나가다가 css를 로드하는 링크 태그나 스타일 태그를 만나면 cssom을 생성하게 된다.
image
cssom은 DOM과 비슷한 트리 구조의 오브젝트 모델입니다. ucss 파싱을 완료하면 html 파싱 중단된 지점부터
다시 html을 파싱하기 때문에
image
DOM 생성을 재개한다. DOM과 css생성이 끝나면, 이둘을 합쳐 렌더트리를 구성한다. 이 때 렌더트리는 렌더링을 위한 트리구조이기 때문에 렌더링에 포함되지 않는 노드들 예를들어 metaTag라던가 scriptTag, css, 즉 디스플레이 등과 같은 것들은 제외하고
구성이 된다.
image
css 파싱 과정과 마찬가지로 랜더링 엔진은 html을 한 줄씩 순차적으로 파싱 하며 DOM을 생산하다가 스크립트태그를 만나면 DOM 생성을 일시 중단한다. 브라우저는 자바 스크립트 코드를 실행하기 위해 렌더링엔진에서 부터 자바 스크립트 엔진으로
제어권을 넘긴다. 이후 자바 스크립트 파싱과 실행이 종료되면 렌더링 엔진으로부터 다시 제어권을 넘겨 html 파싱이
중단된 지점부터 DOM을 생성한다.
만약 자바스크립트코드에 의해 DOM이나 CSSOM이 이용되는 경우 DOM과 CSSOM을 다시 랜더 트리로 결합하고
이를 기반으로 레이 아웃과 패인트 과정을 거쳐 브라우저 화면에 랜더링되게 된다.
이를 리플로우와 리페인트라고 한다. css의 경우에서 알 수 있듯이 브라우저는 동기적으로 즉, 위에서 아래 방향으로 순차적으로 html과 css, 자바스크립트를 파싱하고 실행한다.
이 말은 스크립트태그 위치에 따라 html 파싱 중단되어 DOM 생성이 지연 될 수 있다는 것을 의미한다.
따라서 스크립트태그의 위치는 중요한 의미를 갖는다.

css태그를 상단에 위치시키는 이유

  • 사용자가 흰 화면을 응시하는 시간을 줄이기 위해 (CSS는 렌더링 차단 리소스로 취급됨)
  • Link를 이용하여 스타일 시트를 다운 받는 경우 최대한 빠르게 다운 받기 위해
    -> 브라우저는 모든 외부 스타일 시트가 다운로드 후 CSSOM 트리가 구성될 떄까지 웹 페이지 렌더링을 차단

Script 태그를 하단에 위치시키는 이유

  • HTML 파서는 script 태그를 만나면 파싱을 멈추고 스크립트를 읽기 때문에 웹페이지의 로딩이 그만큼 늦춰질 수 있다.
  • 생성되지 않는 DOM 노드를 읽거나 조작하는 것이 불가능하기 때문에 예상치 못한 오류가 발생할 수 있다.

렌더링의 문제점

  • 동적 UI 관리에 약하다
    -> DOM 트리가 수정될 때마다 새로운 렌더 트리와 레이아웃을 생성하고 Repaint 한다.
  • 단 하나의 요소가 바뀌어도 전체 페이지 정보를 갱신한다.
  • 하나의 페이지에서 많은 동작이 이뤄지는 SPA에서 비효율적이다.

BOM

image

출처. https://www.youtube.com/watch?v=q1fQnGG1bgU