이 글은 LuckyPear 스터디에서 JB Paul 님이 진행한 세미나를 바탕으로 정리한 내용입니다!
안녕하세요! 이 글은 React의 탄생 배경과 더불어 어떤 방식으로 동작하는지에 초점을 맞춰 작성한 글입니다. hooks에 대한 내용은 다른 포스팅에서 다룰 예정입니다.
웹 브라우저가 원본 HTML을 읽어들이고 Style을 입히고 대화형 페이지로 만들어서 뷰포트에 표시하기까지의 과정을 Criticial Rendering Path
라고 합니다.
Criticial Rendering Path 를 대략 두 단계로 나눈다면, 다음과 같습니다.
1. 브라우저는 읽어들인 문서를 파싱하여 어떠한 내용을 페이지에 렌더링 할지 결정하여렌더트리
를 생성합니다.
2. 렌더트리를 바탕으로 실제로 렌더링 합니다.
이때 브라우저가 만든 Render Tree
는 DOM
과 CSSOM
이라는 모델을 통해서 생성됩니다.
먼저 간단히 정의를 알아보겠습니다❗️
DOM
(Document Object Model)은, HTML 요소들의 구조화된 표현이고,
CSSOM
(Cascading Style Sheets Object Model)은, 요소들과 연관된 스타일 정보의 구조화된 표현을 이야기 합니다.
HTML에선 DOM이 있다면, CSS파일에선 CSSOM이 있다고 이해하면 편할 것 같습니다.
결국은 "DOM은 원본 HTMl을 통해 만들어진 객체 기반의 표현 방식"
이고("DOM은 HTML이다"
라는 말은 당연히 틀린 말이 되겠습니다.), HTML 문서의 내용과 구조가 객체 모델
로 변환되었다는 사실이 중요합니다.
이와 같은 코드에서 <html>
이 부모 줄기, 그 안의 태그인 <head>
와 <title>
은 자식 나뭇가지 이며 그 안의 "My first web page"
와 같은 컨텐츠는 잎에 해당한다고 볼 수 있습니다.
📝 DOM과 CSSOM의 차이점
<!doctype html> <html land="ko"> <head> <title>My first web page</title> </head> <body> <h1>Hello, world!</h1> <p style="display: none;">How are you?</p> </body> </html>
DOM
html
ㄴhead
ㄴtitle
ㄴMy first web page
body
ㄴh1
ㄴHello, world!
ㄴp
ㄴHow are you?
CSSOM
html
ㄴhead
ㄴtitle
ㄴMy first web page
body
ㄴh1
ㄴHello, world!
❗️ 차이점을 아시겠나요?
display:none
이 적용된<p>
는 CSSOM에선 그려지지 않습니다!
const h1 = document.querySelectorAll("h1");
h1.forEach((element) => element.style.color='red');
다음과 같이 javascript 코드를 통해 DOM
을 조작할 수 있습니다.
하지만, DOM
을 조작한다고 해서 HTML 코드 자체를 바꿀 순 없습니다. HTML 문서의 코드를 통해 생성된 DOM
을 Javascript 코드를 통해 동적으로 DOM
을 조작하는 것이기 때문입니다.
때문에, DOM은 브라우저나 개발자 도구(F12)에서 보이는 것이 아닙니다.
jQuery React가 등장하기 이전, jQuery는 웹 개발에 빼놓을 수 없는 존재였습니다.
"write less do more"
라는 모토를 들고 2006년에 발표된 jQuery는 쉽고 간단한 코드로 DOM을 효율적으로 조작할 수 있다는 점에서 각광받았습니다.
$('h1').css('color', 'red');
하지만, 웹 페이지가 아닌, 웹 어플리케이션으로 규모가 커짐에 따라 javascript 파일이 커지면서 통제가 어려워졌습니다. 그에 따라 등장한 것이 바로 React와.js 같은 SPA(Single Page Application) 라이브러리 입니다.
위에서 언급했던, SPA에 대해 먼저 알아보겠습니다.
SPA(Single Page Application) 란, 말 그대로 단일 페이지로 구성된 웹 어플리케이션을 말합니다. 위에서 언급했던 전통적인 웹 페이지들은 모든 페이지마다 정적인 HTML, CSS, Javascript 파일을 각각 가지고 있고, 따라서 페이지 간 이동 시 HTML, CSS, Javascript 파일 전부를 서버와 주고 받았기 때문에 속도가 느립니다.
반면 Single Page Application은 필요한 파일들을 최초 1회만 다운로드 합니다. 이후 새로운 페이지 요청 시 페이지 업데이트에 필요한 데이터만 서버로 부터 전달받아 DOM을 조작합니다.
SPA이기 때문에 가지는 특징은 다음과 같습니다.
장점
단점
SPA를 가능하게 했고, React가 각광받게 된 이유가 Virtual DOM
에 있습니다.
Virtual DOM은 DOM에 대한 새로운 접근법을 제시합니다.
React에는 state
와 props
라는 개념이 있습니다. 쉽게 생각하면, 화면에서 변하는 값을 의미합니다.
React는 다음과 같은 경우에
리렌더링
이 일어납니다.
1. Props가 변경되었을 때
2. State가 변경되었을 때
3. forceUpdate() 를 실행하였을 때.
4. 부모 컴포넌트가 렌더링되었을 때
위의 설명과 같이, React는 상태나 속성 값이 변하게 되면 리렌더링 이라는 과정을 통해서 화면에서의 값을 갱신합니다.
말 그대로 렌더링을 다시 한다는 뜻으로, 바뀐 상태나 속성 값으로 화면을 그린다는 뜻 입니다.
React는 값이 변할 때 화면의 깜빡임 없이 빠른 속도로 값을 변경 시키는데, 그 이유가 Virtual DOM
에 있습니다.
Virtual DOM
은 말 그대로 가상의 DOM
을 의미합니다.
만약 상태나 속성값이 변경된 경우, 변경된 값으로 React는 가상의 돔을 그리게 됩니다.
그린 가상의 돔과 실제 브라우저의 돔을 비교하여 변경된 사항만 반영하여 해당 내용을 실제 돔에서 수정한 이후 새로운 화면을 렌더링 하게 되는 것이죠❗️
https://www.youtube.com/watch?v=BYbgopx44vo
(VDOM
을 그리고 실제 브라우저 DOM
을 비교하여 렌더링 하는 과정을 쉽게 알려주는 유투브 영상입니다! 참고하시면 좋을것 같아요😆 )
코드를 통해 좀 더 알아보겠습니다.
class HelloMessage extends React.Component{
render(){
return <div>Hello {this.props.name}</div>;
}
}
ReactDOM.render(<HelloMessage name="Paul" />, mountNode)
여기서 name
이 Peter로 바뀐다면, 화면에서도 "Hello Paul" 에서 "Hello Peter"로 변경될 것 입니다.
앞서 언급한 대로 name
은 props
에 해당하는 값이기 때문에, 변경사항을 감지하고 VDOM을 새로 그리고 브라우저 DOM과 비교하여
바뀐 내용만 브라우저 DOM에 반영하여 새로 화면에 렌더링하게 됩니다.
정리해볼까요?
HelloMessage
에서 "Hello Paul" render에서 return하여 렌더링 중- props의
name
이 Peter로 변경- props(속성)값이 변경되었기 때문에 render함수를 재호출
HelloMessage
에서 Hello Peter를 return- Virtual DOM에서 변경된 내용
(this.props.name)
을 감지, 해당<div>
안의 내용을 DOM에서 수정- 브라우저에서 변경 값을 감지하고 새로운 화면 렌더링
왜 VDOM이 더 빠르고 더 좋고 DOM보다 훨씬 효율적이라는 걸까요?
DOM 조작의 실제 문제는 각 조작이 레이아웃 변화, 트리 변화와 렌더링을 일으킨다는 겁니다. 그래서, 예를 들어 여러분이 30개의 노드를 하나 하나 수정하면, 그 뜻은 30번의 (잠재적인) 레이아웃 재계산과 30번의 (잠재적인) 리렌더링을 초래하게 됩니다.
그에 반해 VDOM은 변화가 일어나면 오프라인 DOM 트리에 적용시킵니다. 이 DOM트리는 렌더링도 되지 않기 때문에 연산 비용이 적은 편입니다. 연산이 끝나고 나면 그 최종적인 변화를 딱 한번만 실제 DOM에 던져주게 됩니다. 이게 바로 연산의 횟수를 줄인다는 뜻 입니다.
또한 어떤게 바뀌었는지, 어떤게 바뀌지 않았는지 알아내는 과정을 VDOM이 자동으로 알아서 해주기 때문에 각광받는 것이라고 생각합니다!
여기까지 React를 쓰게된 이유와, 핵심 개념인 VDOM에 대해서 알아보았습니다.
다음 후편에서는 React의 문법적인 측면과 hooks에 대해서 포스팅 해볼 예정입니다!
감사합니다 😁
와! 정말 똑똑하시네요!