출처: https://www.youtube.com/watch?v=N7qlk_GQRJU

이정환님의 강의를 보고 정리한 글입니다.
브라우저가 화면에 렌더링되는 방식
Critical Rendering Path 과정을 통해서 렌더링을 하게 된다.
전체적인 구조는 다음 사진과 같다.

위의 사진을 구조적으로 세분화시켜서 단계별로 나누면 다음과 같다.
1단계 - html,css 변환
우리가 작성한 html과 css코드를 각각 DOM과 CssObjectModel 변환을 한다.

※ 알고 넘어가기.
DOM이란? Document Object Model의 약자로, html을 브라우저가 해석하기 편한 방식으로 변환한 객체트리를 말한다.
2단계 - Render Tree 생성
1단계에서 만든 dom과 cssom을 합쳐서 Rander Tree라는걸 만든다.
그렇기때문에, 요소들의 배치(html)와 모양(css)을 모두 합친 Rander Tree는 웹 페이지의 '청사진'이라고 불린다.

3단계 - Layout 과정
Rander Tree를 기반으로 실제 웹 페이지 요소들의 배치를 결정함
(html 요소들이 어떤 위치, 어떤 사이즈로 등장할 것인지 계산하는 작업)

4단계 - Painting 과정
실제로 요소들을 화면에 그려내는 과정이다.

이렇게 4단계까지의 작업을 거쳐서 브라우저에 렌더링이된다.
이 모든 과정을 'Critical Rendering Path' 이라고 한다.
그러면 여기서 업데이트 과정이 일어났을때 어떻게 이루어지는지 살펴보자.
업데이트가 이루어지는 방식
1. javascript가 dom을 수정하면 업데이트가 발생
2. DOM이 수정되면 Critical Rendering Path가 다시 실행됌

innerHTML, appendChild, removeChild 기타 등등의 DOM api를 이용해서 dom을 수정하게 되면,
브라우저가 DOM의 변경을 감지하여 Rander Tree를 다시 만들고, Layout을 다시 잡고, Painting을 다시 해서 변화된 UI를 화면에 다시 그려주는 과정을 거친다.
그런데 자바스크립트로 dom을 직접적으로 조작해 업데이트를 구현할 때 조심해야하는 점이 있다.
⚠️Layout,Painting은 매우 비싼 과정이다.⚠️
비싸다는건 연산이 많이 필요하다는거고, 시간이 오래걸린다는 뜻이다.

layout을 다시 한다 -> Reflow 라고 한다.
Painting을 다시한다 -> Repaint 라고 한다.
그렇기 때문에 자바스크립트로 DOM을 조작할 땐 DOM의 수정 횟수를 최소화 하는게 중요하다.
ex): 요소에 300개의 업데이트가 필요하다고해서 dom을 막무가내로 300번 바로 수정시켜버리면 reflow와 repaint가 각각 300번씩 발생하게되어 웹서비스의 심각한 성능 저하가 일어남
좋지못한 업데이트 방식

리스트 추가하기! 버튼을 누르면 0부터 3000개의 리스트를 만드는 코드이다.
반복문 안에 innerHTML을 매 반복마다 수정하고있는 코드로, 되게 안좋은 방식이다.
성능 측정 결과: 4,500ms가 걸렸다고 한다. (4.5초)
좋은 업데이트 방식

DOM 딱 한번만 수정함 - reflow와 repaint도 한번만 일어
성능 측정 결과: 250ms가 걸림
결론
자바스크립트를 이용해 dom을 직접 조작해서 업데이트를 구현할 때에는,
동시에 발생되는 업데이트들을 최대한 모아 dom 수정 횟수를 최소한으로 가져가면서 그로인해 발생되는 reflow와 repaint를 최소화 해야한다.
하지만..
서비스의 규모가 커질수록 점점 힘들어짐
그래서 리액트 같은 라이브러리를 사용하게된것
참고로, 리액트에서는
동시에 발생되는 업데이트들을 최대한 모아 dom 수정 횟수를 최소한으로 가져가면서 그로인해 발생되는 reflow와 repaint를 최소화 ' 해주는 작업을 자동으로 해준다.
내부적으로 동시에 발생되는 업데이트들을 다 모아서 최소한의 횟수로 dom을 수정할 수 있도록 추상화되어있다고 생각하자.