Gom3rye

Who Am I] Virtual DOM 본문

웹 개발

Who Am I] Virtual DOM

Gom3rye 2022. 8. 31. 17:59
  • 브라우저는 화면을 그리기 위해 DOM(Document Object Model) 개념을 사용한다.
  • DOM은 html 파일 내용을 토대로 만들어지는데 js와 같은 script언어로 수정할 수 있도록 만들어진 웹페이지의 객체 지향 표현이라고 할 수 있다.
  • DOM은 화면을 그리기 위해 필요한 정보가 tree 형태로 저장된 data이다.
  • 기존에는 화면을 그릴 때마다 Jquery나 getElementById를 사용해 특정 DOM 노드를 수정하거나 삭제했는데 이렇게 특정 노드에 crud 작업을 수행하는 것은 많은 비용을 초래했다.
    -> 왜냐하면 실제 DOM에는 브라우저가 화면을 그리는데 필요한 모든 정보가 들어가 있기 때문이다.
  • 이런 비용 문제를 해결하기 위해 React에서 사용하는 Virtual DOM 개념이 나왔다. 일종의 DOM 캐싱, 버퍼링이라고 볼 수 있다.
  • 리액트는 실제 DOM의 변경 사항을 빠르게 반영하기 위해 가상 DOM을 만들어 내부적으로 반영한다.
  • 예를 들어 특정 노드를 변경시키면 특정 노드의 하위 노드들을 다 검사한 후 변경된 사항만 DOM api를 호출해서 변경시킨다. 

실습

JS로 1초마다 변하는 숫자가 담긴 버튼 생성

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="root"></div>
    <script>
      const rootElement = document.getElementById("root");  // id가 root인 element 가져와서 rootElement로 선언
      
      function draw() {
        const number = Math.floor(Math.random() *9 +1);
        const element = `
          <button>${element}</button>
        `;
        rootElement.innerHTML = element;
      }
      setInterval(draw, 1000);   // 1초마다 draw함수를 호출한다.
    </script>
  </body>
</html>

- 개발자 도구를 열어서 확인해보면 div 태그까지 함께 반짝이며 변하는 것을 볼 수 있다.

 

React로 1초마다 변하는 숫자가 담긴 버튼 생성

<!DOCTYPE html>
<html lang="en">
  <body>
    <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>   // react를 가져오기 위한 코드
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>   // 바벨 스크립트 넣어주기
    
    <div id="root"></div>
    <script type="text/babel">   // type="text/babel"을 넣어주어야 jsx 사용 가능
    <script>
      const rootElement = document.getElementById("root");  // id가 root인 element 가져와서 rootElement로 선언
      
      function draw() {
        const number = Math.floor(Math.random() *9 +1);
        const element = (
         <React.Fragment>   // jsx문법을 사용할 때는 <React.Fragment>로 감싸줘야 한다. 
         // (리액트를 사용하기 위한 문법인 jsx를 쓸 때 return문 안에는 반드시 하나의 최상위 태그가 있어야 하기 때문) 
          <button>{number}</button>
          <div>
            <p>{number}</p>
          </div>
         </React.Fragment>
        );
        ReactDOM.render(element, rootElement);
      }
      setInterval(draw, 1000);   // 1초마다 draw함수를 호출한다.
    </script>
  </body>
</html>

- 버튼 태그 부분만 반짝이면서 변하는 것을 볼 수 있다.

- reflow와 repaint의 과정을 최소화해줄 수 있음을 확인할 수 있다.

728x90
반응형