1. 문서 객체 모델 DOM
1.1 DOM
DOM은 Document Object Model 의 약어이며, 메모리에 객체로 웹 페이지 문서 구조를 표현하는 방법이다.
XML이나 HTML로 작성한다.
DOM은 프로그래밍 언어가 트리 형태인 DOM 구조에 접근할 수 있는 방법을 제공해 특정 노드(문서, 구조, 스타일 등)를 찾거나 수정, 제거, 원하는 곳에 삽입할 수 있다.
웹 브라우저는 DOM을 활용해 객체에 Javascript와 CSS를 적용한다.
API (web or XML page) = DOM + JS (scripting language)
DOM과 접근 방법에 대해 추가로 알아보기 위해 아래의 링크를 참고하자
1.2 DOM은 진짜 느린가?
이렇게 생성된 DOM을 웹 브라우저에서 DOM API를 이용해 사용하는데, DOM이 느리다는 이야기를 들은 적이 있다.
진짜로 DOM은 느릴까?
나는 그럴수도 있고, 아닐 수도 있다 라고 생각하고 싶다.
우선 DOM에는 한 가지 치명적인 문제가 있다.
동적 UI에 최적화되어 있지 않다는 것이다.
HTML은 자체적으로는 정적이다.
하지만 Javascript를 함께 이용한다면 HTML도 동적으로 만들 수 있다.
DOM 자체는 빠르다. DOM 객체를 읽고 쓸 때의 성능은 JS 객체를 처리할 때의 성능과 비슷하다.
하지만, 규모가 큰 프로젝트에서는 수 많은 데이터가 로딩된다.
데이터가 많아지면 표현 혹은 업데이트 해야하는 요소(element)의 수 또한 많아진다.
그로인해 DOM 조작이 많아지게 되는데 DOM에 변화가 발생하면 웹 브라우저가 CSS 재연산, 레이아웃 구성, 페이지 리페인팅을 하게된다.
이 과정에서 시간, 즉 성능이 허비되는 것이다.
이렇게 규모가 큰 웹 애플리케이션에서 직접 DOM에 접근해 변화를 주는 것은 성능 이슈가 발생할 수 있다.
DOM을 조작할 때 마다 페이지를 새로 그리기 때문에 업데이트가 잦으면 성능이 저하될 수 있다.
그래서 React에서는 Virtual DOM 방식을 사용해 DOM 업데이트를 추상화함으로써 DOM 처리 횟수를 최소화 하고 효율적으로 진행하는 방향으로 개발되었다.
2. React 에서의 Virtual DOM 가상 돔
리액트에 대해 이야기하기 전에 VDOM에 대해 이야기 해보자
2.1 Virtual DOM
Virtual DOM, 가상 돔은 실제 DOM을 추상화해 메모리에 JS 객체 형태로 저장된 복사본이라 생각하면 쉽다.
Virtual DOM은 DOM 조작이 많은 경우 변경사항들을 모아 단 한번의 DOM조작으로 실제 DOM 업데이트를 하기 위해 사용한다.
❗❗ 하지만❗❗,
Virtual DOM 객체는 실제 DOM 객체을 복사한 것이지만 직접적인 접근과 조작은 하지못한다.
즉, 화면에 보여지는 내용은 직접 수정하지 못한다는 것이다.
그렇다면 왜 Virtual DOM을 사용하는 것인가?
바로 변경된 요소만 업데이트 하기 위함이다.
1.2에서 DOM 조작이 많아지게 되면 성능이 저하될 수 있다고 했다.
하지만 램에 DOM을 복사해 변경사항을 모아 다시 실제 DOM에 보내는 이 Vitual DOM이 더 느리지 않을까??
사실 Virtual DOM은 데이터가 많고 실시간으로 변하는 대규모 프로젝트에서 유의미한 효과를 보이지만 대부분의 상황에서 웹 페이지에 Virtual DOM을 적용할 필요까지는 없다.
리액트 매뉴얼네는 이런 말이 있다.
우리는 다음 문제를 해결하려고 리액트를 만들었습니다.
지속적으로 데이터가 변화하는 대규모 애플리케이션 구축하기
이는 Virtual DOM 이 일부 경우에서는 큰 효과를 못 보여준다고 생각할수 있게 말하는것 같다.
그렇다면 React에서 Virtual DOM이 어떻게 사용되는지 알아보자❗❗
2.2 React에서 Virtual DOM
리액트는 유지보수가능한 애플리케이션을 만드는 것을 도와주고, 대부분의 경우에 "충분히 빠르다"
위의 문구를 기억하자.
리액트에서 데이터(State)가 변해 실제 DOM을 업데이트할 때는 세 가지 절차를 따른다.
- 데이터를 업데이트하면(State가 변경되면) 전체 UI를 Virtual DOM에 리렌더링 한다.
- 이전 Virtual DOM에 있던 내용과 현재 내용을 비교한다.
- 바뀐 부분만 실제 DOM에 적용한다.
정리하자면 React는 State가 변경될 때마가 리렌더링이 발생한다.
이 시점에 새로운 내용이 담긴 Virtual DOM을 생성한 뒤, 이전 Virtual DOM과 비교후 바뀐 곳만 실제 DOM에 적용한다.
위의 글에서 이전 Virtual DOM과 업데이트된 Virtual DOM이 있다고 적었다.
이는 React에서 2개의 Virtual DOM을 갖고 있다는 것을 이야기한다.
렌더링 이전에 첫번째 Virtual DOM과 업데이트 이후 발생할 두번째 Virtual DOM을 비교해 어떤 Element가 변했는지를 알아냅니다.
이 과정을 Diffing이라 합니다.
Diffing은 알고리즘을 이용해 효율적이고 신속하게 Element의 변화를 파악합니다.
(Dffing에 대해서는 다음에 더 공부해보자)
React는 이렇게 두 Virtual DOM의 Element 차이를 파악하고 이 부분만 실제 DOM에 적용하는 것입니다.이 과정을 Reconciliation(재조정)이라 하며, 이 과정이 효율적인 이유는 Batch Update 때문입니다.
Batch Update
는 변경된 모든 Element들을 집단화시켜 한번에 실제 DOM에 적용하는 방식입니다.즉, 100개의 변경 사항이 있다면 100번 반복해 수정하는 것이 아니라 한번에 집단화시켜 단 한번에 적용하는 것입니다.
이는 변경 사항을 한번에 받아와 한번에 적용한다는 점에서 DOM 조작 비용을 효율적으로 관리할 수 있다는 것을 보여준다.
하지만 VDOM이 항상 DOM을 직접 조작하는 것보다 빠른것이 아니기에 React 또한 대부분의 경우에는 충분히 빠를지언정, 일부의 경우에는 React를 사용하지 않는 것이 더 빠를 수 있기에 항상 이를 생각하며 사용하도록 하자.
3. 정리
3.1 VDOM은 DOM 보다 빠른가?
대답은 "NO"
위에서 이야기 했지만 DOM이 느리다는 것은 미신이다.
대부분의 경우에는 DOM 조작만으로 충분하다.
하지만 DOM 조작이 많고 수시로 이뤄지는 환경에서는 VDOM이 성능면에서 좋은것이 맞다.
즉, 상황에 맞게 VDOM과 DOM을 선택해 사용하자 라는 말을 하고싶다.
3.2 그렇다면 React는 모든 상황에서 빠른가?
이것 역시 대답은 "NO"
React가 DOM 보다 빠르다는 것은 미신이다.
React는 유지보수 가능한 애플리케이션을 만드는 것을 도와주며, 대부분의 경우에 "충분히 빠르다".
아까도 말했지만 React는 VDOM을 많은 데이터가 변하는 대규모 애플리케이션에 사용하기 위해 만들었다 했다.
그리고 VDOM이라는 기술이 DOM 보다 항상 빠르다는 것이 아니라는 것도 위에서 이야기 했다.
내 생각을 종합하자면, 자신이 개발하는 프로젝트나 애플리케이션의 규모와 상황을 파악하고 올바르게 사용할수 있는 개발자가 되라는 것이다.
무턱대고 "React가 빠르니까 React를 사용하자" 가 아니라 제대로 알고 기술을 사용하자 라는 것이다.
참고 링크
- https://stackoverflow.com/questions/21965738/what-is-virtual-dom
- https://www.codecademy.com/article/react-virtual-dom
- https://callmedevmomo.medium.com/virtual-dom-react-%ED%95%B5%EC%8B%AC%EC%A0%95%EB%A6%AC-bfbfcecc4fbb
- https://velog.io/@woohm402/virtual-dom-and-react
- https://legacy.reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom
- https://ko.legacy.reactjs.org/blog/2013/06/05/why-react.html
- https://joong-sunny.github.io/react/react2/#%EF%B8%8F%EC%A7%88%EB%AC%B81-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B0%80%EC%83%81%EB%8F%94-%EC%99%9C%EC%8D%A8%EC%9A%94
'React > 리액트 기초' 카테고리의 다른 글
React) State (0) | 2023.11.28 |
---|---|
React) 리액트 컴포넌트와 Props (0) | 2023.11.28 |
React) Batching과 React18의 Automatic Batching (0) | 2023.11.24 |
React) Diffing 알고리즘 (비교 알고리즘) (0) | 2023.11.23 |
React) 컴포넌트와 렌더링 (0) | 2023.11.17 |