현대의 웹 개발은 과거와는 많이 달라졌다.
특히 자바스크립트 생태계는 엄청난 속도로 발전하고 있는데, 이번 포스팅을 통해서 모던 자바스크립트의 주요 특징 중 하나인 Virtual DOM과 JavaScript의 기본적인 문법에 대해서 살펴보도록 하자
우선 DOM이란 무엇인지부터 이해해보자
웹 페이지를 구성하는 HTML 문서는 DOM이라는 형태로 표현된다.
DOM은 HTML이라는 Root Element에서 시작하여 그 하위에 있는 모든 태그들을 Tree 구조로 표현한 것이다.
그렇다면 DOM은 어떤 특징이 있을까?
DOM의 특징
- HTML 문서의 프로그래밍 인터페이스
- 문서를 논리 트리로 표현
- 노드는 DOM Tree의 구성 요소이며, 각 노드는 요소와 속성, 이벤트 핸들러 등으로 구성 됨
- JavaScript를 통해 DOM 내의 요소와 속성을 동적으로 생성, 수정, 삭제를 할 수 있음
여기서 JavaScript는 DOM과 동적으로 상호작용을 할 수 있다는 포인트를 알아두자.
다시 말하면 사용자의 액션을 통해 DOM을 수정하고 이를 통해 동적인 웹 페이지를 만들 수 있다는 것이다.
DOM Tree에 대해서 알아보기 전에 우선 전체적인 흐름부터 살펴보자
DOM Tree를 만드는 것은 웹 페이지를 렌더링하기 위한 과정의 일부이다.
렌더링 과정은 다음과 같다!
Render Course
1. Loading
- HTML, CSS, JavaScript 등 리소스를 로드한다.
2. 파싱과 Tree 생성
- HTML 파싱 -> DOM Tree 생성
- CSS 파싱 -> CSSOM Tree 생성
- JavaScript 파싱 -> AST 생성 및 실행
-<script>
태그를 만나면 파싱을 중단하고 JS를 실행한다.
- JavaScript는 DOM API를 사용해서 DOM Tree를 조작할 수 있다.
- CSSOM API를 이용해서 스타일을 조작할 수 있다.
3. Render Tree 생성
- DOM Tree와 CSSOM Tree를 결합
- 화면에 표시될 요소만 포함한다.
4. Layout
- 요소들의 위치와 크기를 계산한다.
5. Paint
- 실제 화면에 픽셀로 그린다.
위 과정을 통해 JavaScript의 실행은 파싱 단계에서 일어난다는 것과 그 후에 Render Tree가 생성되는걸 더 명확하게 알 수 있다.
JavaScript로 DOM이나 CSSOM을 수정하면 다시 Render Tree를 생성하고 Layout, Paint 과정을 거치게 되는 것이다.
웹 애플리케이션이 복잡해지면서 DOM 조작이 빈번하게 발생하게 되었고, 이는 성능 저하의 주요 원인이 되었다.
예를 들어, 하나의 목록에서 한 항목만 변경되어도 전체 목록을 다시 렌더링해야 했다.
DOM 조작의 문제점
- 잦은 업데이트로 인한 리플로우/리페인트
- 불필요한 DOM Tree 재구성
- 브라우저 렌더링 엔진의 과도한 작업
이러한 문제를 해결하기 위해 Virtual DOM이 등장했다.
Virtual DOM은 실제 DOM의 가벼운 복사본으로, 메모리상에 존재한다.
위 사진은 일반적인 DOM과 Virtual DOM의 차이점을 그림으로 나타내고 있다.
DOM의 업데이트 과정을 조금 더 자세히 알아보자
Virtual DOM의 업데이트 과정
1. 초기 렌더링
- 실제 DOM의 구조를 복사해 Virtual DOM 생성
- 최초 렌더링 시에는 전체 DOM Tree 생성
2. 상태 변경 발생
- 데이터가 변경되면 새로운 Virtual DOM Tree 생성
- 새로 생성된 Virtual DOM Tree는 업데이트된 상태를 반영
3. 비교 프로세스 수행
- 위 사진 기준으로 차이점 식별 프로세스에 해당된다.
- Virtual DOM은 새로운 생긴 DOM Tree와 이전 DOM Tree 사이의 비교 프로세스를 수행
- 해당 과정으로 최소한의 변경 사항을 식별
4. 최소 업데이트
- 식별된 차이점만 실제 DOM에 업데이트를 적용
- 즉, 실제 DOM에 필요한 업데이트만 적용
간단하게 React 컴포넌트 예시를 통해서 DOM Tree의 변경 과정을 생각해보자
function TodoList({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
위와 같은 코드에서 items의 배열이 변경되었다면 어떻게 될까?
아마 아래 순서로 DOM Tree가 변경될 것이다.
- 새로운 Virtual DOM Tree 생성
- 이전 트리와 비교하여 변경된 item을 식별
- 변경된 item에 의해 추가로 변경되는 하위 노드를 식별
- Virtual DOM Tree에 업데이트하여 리렌더링 수행
위 과정을 통해 어떻게 Virtual DOM Tree가 변할지 살펴보았다.
이러한 방식으로 Virtual DOM은 실제 DOM 조작을 최소화하고, 애플리케이션의 성능을 최적화할 수 있다.
ES6(ECMAScript 2015) 이후 자바스크립트는 큰 변화를 맞이했다.
개발자들의 생산성과 코드의 품질을 높여주는 다양한 기능들이 추가되었다.
주요 변경사항
- 변수 선언: let, const
- 함수 표현: 화살표 함수 도입
- 문자열 처리: 템플릿 리터럴
- 구조 분해: 디스트럭처링 할당
- 반복문: for...of 구문
- 모듈화: import/export 구문
- 객체지향: 클래스 문법
- 비동기 처리: Promise
- 새로운 자료구조: Map, Set
- 데이터 처리: Rest/Spread 연산자
관련 내용은 이전에 관리했던 블로그의 포스팅 내용에 있으니 혹시 궁금하면 참고하면 좋겠다!
JavaScript 알쓸신잡 - 1
JavaScript 알쓸신잡 - 2
이번 포스팅에서는 DOM과 Virtual DOM의 개념, 그리고 브라우저의 렌더링 과정에 대해 자세히 알아보았다.
특히 브라우저가 어떻게 HTML, CSS, JavaScript를 파싱하고 화면을 렌더링하는지 그 과정을 이해할 수 있었다. (해당 내용은 기본이니 알아두도록 하자 🤣)
DOM 조작의 한계를 극복하기 위해 등장한 Virtual DOM은 현대 웹 개발에서 중요한 개념이 되었으며, ES6+ 문법의 도입으로 자바스크립트는 더욱 강력하고 효율적인 언어로 발전했다.
이러한 새로운 문법과 기능들은 개발자들이 계속 공부해야하는 이유를 제공하는 것 같다..!