개요
리액트(react.js)나, 뷰(Vue.js)는 가상돔(Virtual DOM)을 사용해서 원하는 화면을 브라우저에 그려주는데,
자체적으로 상당히 효율적인 알고리즘을 사용해서 그려주기 때문에 그 속도가 굉장히 빠르다.
그렇다면 돔은 무엇이고 가상돔은 대체 무엇인가?
DOM
1) DOM이란?
가상돔을 이해하기 위해서는 먼저 DOM(Document Object Model)을 이해할 필요가 있다.
브라우저를 돌아다니다 보면 수 많은 컴포넌트로 구성된 웹페이지들을 보게 되는데,
그 페이지를 문서(document)라고 하고, 페이지를 이루는 컴포넌트를 엘리먼트(element)라고 한다.
DOM은 이 엘리먼트를 tree 형태(= DOM TREE)로 표현한 것이다.
트리의 요소 하나하나를 ‘노드’라고 부르고, 각각의 ‘노드’는 해당 노드에 접근과 제어(DOM 조작)를 할 수 있는 API를 제공한다.
2) DOM 사용 예시
// id가 demo인 녀석을 찾아, 'Hello World!'를 대입해줘.
document.getElementById("demo").innerHTML = "Hello World!";
// p 태그들을 모두 가져와서 element 변수에 저장해줘
const element = document.getElementsByTagName("p");
// 클래스 이름이 intro인 모든 요소를 가져와서 x 변수에 저장해줘
const x = document.getElementsByClassName("intro");
form validation
function validateForm() {
let x = document.forms["myForm"]["fname"].value;
if (x == "") {
alert("Name must be filled out");
return false;
}
}
<form name="myForm" action="/action_page.php" onsubmit="return validateForm()" method="post">
Name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
가상DOM(Virtual DOM)
(1) 가상DOM이란?
리액트는 가상DOM을 이용해서 실제DOM을 변경하는 작업을 상당히 효율적으로 수행한다.
가상DOM은 실제 DOM과 구조가 완벽히 동일한 복사본 형태라고 보면 된다.
실제 DOM은 아니지만, 객체(object) 형태로 메모리에 저장되기 때문에
실제 DOM을 조작하는 것 보다 훨씬 더 빠르게 조작을 수행할 수 있다.
가상 DOM이 실제 DOM을 변경하는 것은 아니라면, 도대체 어떻게 화면이 바뀌게 되는 것일까?
(2) DOM 조작 과정
만일 인스타그램의 좋아요 버튼을 누른다면
화면이 바뀌어야 한다.
빨간색 하트에 해당되는 엘리먼트 DOM 요소가 갱신돼야 한다.
[STEP 1]
이 과정에서 리액트는 항상2가지 버전의 가상DOM을 가지고 있다.
- 화면이 갱신되기 전 구조가 담겨있는 가상DOM 객체
- 화면 갱신 후 보여야 할 가상 DOM 객체
리액트는 state가 변경돼야만 리렌더링이 된다. 그 때, 바로 2번에 해당되는 가상 DOM을 만든다.
[STEP 2 : diffing]
state가 변경되면 2번에서 생성된 가상돔과 1번에서 이미 갖고있었던 가상돔을 비교해서 어느 부분(엘리먼트)에서 변화가 일어났는지를 상당히 빠르게 파악해낸다.
[STEP 3 : 재조정(reconciliation)]
파악이 다 끝나면, 변경이 일어난 그 부분만 실제 DOM에 적용시켜준다.
적용시킬 때는, 한건 한건 적용시키는 것이 아니라, 변경사항을 모두 모아 한 번만 적용을 시킨다(Batch Update 🔥)
(3) Batch Update
여러 개의 state 변경이 동시에 처리되어 , 한 번의 리렌더링으로 업데이트되는 개념. 일반적으로 상태를 업데이트할 때 'batch update'가 발생한다.
React는 상태를 업데이트할 때 비동기적으로 처리되며, 여러 상태 업데이트가 동시에 발생할 때 이를 모아 효율적으로 처리한다. 이런 방식으로 인해 성능이 향상되고, 불필요한 리렌더링이 방지된다.
import React, { useState } from 'react';
const ExampleComponent = () => {
const [count, setCount] = useState(0);
const handleClick = () => {
// 여러번의 상태 업데이트 호출
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
// ...
// React는 이를 모아서 처리하고, 최종적으로 한 번의 리랜더링을 수행
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increase Count</button>
</div>
);
};
export default ExampleComponent;
위 코드에서 handleClick 함수에서 여러 번의 setCount를 호출하더라도 React는 내부적으로 이를 모아서 처리하고, 최종적으로 한 번의 리렌더링만 발생시킨다. 이로 인해 불필요한 중복 리렌더링을 방지하면서 성능을 최적화시킬 수 있다.
'웹개발 > react' 카테고리의 다른 글
[React] Redux + 설정 카운터 프로그램 만들기 (1) | 2024.01.29 |
---|---|
[React] 리덕스(Redux)란 무엇인가? (1) | 2024.01.27 |
React Hooks - useContext(Context API)란 무엇인가? (1) | 2024.01.24 |
React에서 자주 사용하는 자바스크립트 배열 API (0) | 2024.01.22 |
React 정의 및 SPA 프레임워크 종류 (0) | 2024.01.17 |