
DOM
- 웹페이지에 대한 인터페이스
- 브라우저가 웹페이지의 콘텐츠와 구조를 어떻게 보여줄지에 대한 정보를 담고 있음
브라우저 렌더링 과정
- 브라우저가 사용자가 요청한 주소를 방문해 HTML 파일을 다운로드함
- 브라우저의 렌더링 엔진은 HTML을 파싱해 DOM 노드로 구성된 DOM 트리를 만듦
- 2번 과정에서 CSS 파일을 만나면 해당 CSS 파일도 다운로드 함
- 브라우저의 렌더링 엔진은 CSS도 파싱해 CSS 노드로 구성된 CSSSOM트리를 만듦
- 브라우저는 2번에서 만든 DOM 노드를 순회하는데, 여기서 모든 노드를 방문하는 것이 아니고 사용자 눈에 보이는 노드만 방문함
- 5번에서 제외된, 눈에 보이는 노드를 대상으로 해당 노드에 대한 CSSOM 정보를 찾고 여기서 발견한 CSS 스타일 정보를 이 노드에 적용함
- 레이아웃 : 각 노드가 브라우저 화면의 어느 좌표에 정확히 나타나야 하는지 계산하는 과정
- 페인트 : 레이아웃 단계를 거친 노드에 색과 같은 실제 유효한 모습을 그리는 과정
가상DOM의 탄생 배경
- 브라우저가 웹페이지를 렌더링하는 과정은 매우 복잡하고 많은 비용이 듬
- 또한 요즘 대다수의 앱은 렌더링 완료된 이후에 사용자의 인터랙션을 통해 다양한 정보를 노출함
- 한 요소의 노출 여부나 사이즈가 변경되는 등 요소의 위치와 크기를 다시 계산하는 시나리오는 레이아웃과 리페인팅 과정이 필연적으로 발생하기 때문에 비용이 더 많이 듬
- DOM 변경이 일어나는 요소가 많은 자식 요소를 가지고 있는 경우에는 하위 자식 요소도 덩달아 변경돼야 하기 때문에 이도 많은 비용이 듬
- 특히 하나의 페이지에서 모든 작업이 일어나는 싱글 페이지 애플리케이션에서는 추가 렌더링 작업이 더욱 많아짐 (대신 깜빡이는 현상은 덜함)
- 이러한 문제들을 모두 해결하기 위해 탄생한 것이 바로 가상 DOM
가상DOM
- 실제 브라우저의 DOM이 아닌 리액트가 관리하는 가상의 DOM
- 웹페이지가 표시해야 할 DOM을 일단 메모리에 저장하고 리액트가 실제 변경에 대한 준비가 완료됐을 때 실제 브라우저의 DOM에 반영함
- 이렇게 DOM 계산을 브라우저가 아닌 메모리에서 계산하는 과정을 한 번 거치게 된다면 실제로는 여러 번 발생했을 렌더링 과정을 최소화할 수 있음
리액트 파이버(React Fiber)
- 가상 DOM과 렌더링 과정 최적화를 가능하게 해주는 것
- 리액트에서 관리하는 평범한 자바스크립트 객체
- 파이버의 구성 요소
- Fiber 노드 : 파이버 알고리즘이 사용하는 데이터 구조
- 알고리즘 : 기존의 스택 기반 알고리즘과 다른 재조정 알고리즘, 비동기적이고 우선순위 기반으로 작업 처리
- 스케줄러 : 작업의 우선순위를 관리하고 중요한 작업을 먼저 처리함. 작업을 작은 단위로 나누어 비동기적으로 처리할 수 있도록 함
- 파이버는 파이버 재조정자가 관리
- 파이버 재조정자 : 가상 DOM과 실제 DOM을 비교해 변경 사항을 수집하며, 이 둘 사이에 차이가 있으면 변경에 관련된 정보를 가지고 있는 파이버를 기준으로 화면에 렌더링을 요청하는 역할
- 리액트 웹 애플리케이션에서 발생하는 애니메이션, 레이아웃, 그리고 사용자 인터렉션에 올바른 결과물을 만드는 반응성 문제를 해결하는 것
- 파이버의 역할
- 작업을 작은 단위로 분할하고 쪼갠 다음, 우선순위를 매김
- 이러한 작업을 일시 중단하고 나중에 다시 시작 가능
- 이전에 했던 작업을 다시 재사용하거나 필요하지 않은 경우 폐기할 수 있음
- 이러한 모든 과정이 비동기로 일어남 => 기존 렌더링 스택의 비효율성을 타파하기 위함
- 파이버는 하나의 element에 하나가 생성되는 1:1 관계를 가짐
- 파이버는 state가 변경되거나 생명주기 메서드가 실행되거나 DOM의 변경이 필요한 시점 등에 실행됨
리액트의 동작 단계
- 렌더 단계 : 리액트는 사용자에게 노출되지 않는 모든 비동기 작업을 수행함. 파이버의 작업, 우선순위를 지정할 수 있고, 우선순위가 높은 작업이 있다면 중단시키고 나중에 재개할 수 있음
- 커밋 단계 : DOM에 실제 변경 사항을 반영하기 위한 작업인 commitWork()가 실행됨. 이는 동기식으로 일어나고 중단될 수도 없음
파이버 트리
- 리액트 내부에서 두 개가 존재함 => 더블 버퍼링을 위함(커밋 단계)
- 현재 모습을 담은 파이버 트리
- 작업 중인 상태를 나타내는 workInProgress 트리
더블 버퍼링
- 리액트 파이버의 작업이 끝나면 리액트는 단순히 포인터만 변경해 workInProgress 트리를 현재 트리로 바꿈
- 먼저 현재 UI 렌더링을 위해 존재하는 트리인 current를 기준으로 모든 작업이 시작됨
- 만약 업데이트가 발생하면 파이버는 리액트에서 새로 받은 데이터로 새로운 workInProgress 트리를 빌드하기 시작함
- 빌드 작업이 끝나면 다음 렌더링에 이 트리를 사용함
- workInProgress 트리가 UI에 최종적으로 렌더링되어 반영이 완료되면 current가 이 workInProgress로 변경됨
파이버의 작업 순서
- 일반적인 파이버 노드의 생성 흐름
- 리액트는 beginWork() 함수를 실행해 파이버 작업을 수행하는데, 더 이상 자식이 없는 파이버를 만날 때까지 트리 형식으로 시작됨
- 위의 작업이 끝나면 그 다음 completeWork() 함수를 실행해 파이버 작업을 완료함
- 형제가 있다면 형제로 넘어감
- 2,3번이 모두 완료되면 return으로 돌아가 자신의 작업이 완료됐음을 알림
파이버와 가상 DOM
- 파이버는 리액트 컴포넌트에 대한 정보를 1:1로 가지고 있는 것
- 파이버는 리액트 아키텍처 내부에서 비동기로 이루어짐
- 실제 브라우저의 구조인 DOM에 반영하는 것은 동기적으로 일어나야 함
- 작업을 미리 가상 즉, 메모리 상에서 먼저 수행해 최종적인 결과물만 실제 DOM에 적용하는 것이 가상 DOM
- 개발자가 직접 DOM을 수동으로 하나하나 변경해야 한다면 어떤 값이 바뀌었는지, 또 그 값에 따라 어떠한 값이 변경됐고 이와 관련된 것들이 무엇이었는지 파악하기 어려움
- 이러한 어려움을 리액트 내부의 파이버와 재조정자가 내부적인 알고리즘을 통해 관리해 줌으로써 대규모 웹 애플리케이션을 효율적으로 유지보수하고 관리할 수 있게 됨
'FE > 리뷰' 카테고리의 다른 글
[모던 리액트 딥다이브] 2.4장 렌더링 (0) | 2024.07.13 |
---|---|
[모던 리액트 딥다이브] 2.3장 클래스 컴포넌트와 함수 컴포넌트 (0) | 2024.07.07 |
[모던 리액트 딥다이브] 2.1장 JSX (0) | 2024.07.07 |
[모던 리액트 딥다이브] 1.7장 타입스크립트 (0) | 2024.06.29 |
[모던 리액트 딥다이브] 1.6장 리액트에서 자주 사용하는 자바스크립트 문법 (0) | 2024.06.27 |

DOM
- 웹페이지에 대한 인터페이스
- 브라우저가 웹페이지의 콘텐츠와 구조를 어떻게 보여줄지에 대한 정보를 담고 있음
브라우저 렌더링 과정
- 브라우저가 사용자가 요청한 주소를 방문해 HTML 파일을 다운로드함
- 브라우저의 렌더링 엔진은 HTML을 파싱해 DOM 노드로 구성된 DOM 트리를 만듦
- 2번 과정에서 CSS 파일을 만나면 해당 CSS 파일도 다운로드 함
- 브라우저의 렌더링 엔진은 CSS도 파싱해 CSS 노드로 구성된 CSSSOM트리를 만듦
- 브라우저는 2번에서 만든 DOM 노드를 순회하는데, 여기서 모든 노드를 방문하는 것이 아니고 사용자 눈에 보이는 노드만 방문함
- 5번에서 제외된, 눈에 보이는 노드를 대상으로 해당 노드에 대한 CSSOM 정보를 찾고 여기서 발견한 CSS 스타일 정보를 이 노드에 적용함
- 레이아웃 : 각 노드가 브라우저 화면의 어느 좌표에 정확히 나타나야 하는지 계산하는 과정
- 페인트 : 레이아웃 단계를 거친 노드에 색과 같은 실제 유효한 모습을 그리는 과정
가상DOM의 탄생 배경
- 브라우저가 웹페이지를 렌더링하는 과정은 매우 복잡하고 많은 비용이 듬
- 또한 요즘 대다수의 앱은 렌더링 완료된 이후에 사용자의 인터랙션을 통해 다양한 정보를 노출함
- 한 요소의 노출 여부나 사이즈가 변경되는 등 요소의 위치와 크기를 다시 계산하는 시나리오는 레이아웃과 리페인팅 과정이 필연적으로 발생하기 때문에 비용이 더 많이 듬
- DOM 변경이 일어나는 요소가 많은 자식 요소를 가지고 있는 경우에는 하위 자식 요소도 덩달아 변경돼야 하기 때문에 이도 많은 비용이 듬
- 특히 하나의 페이지에서 모든 작업이 일어나는 싱글 페이지 애플리케이션에서는 추가 렌더링 작업이 더욱 많아짐 (대신 깜빡이는 현상은 덜함)
- 이러한 문제들을 모두 해결하기 위해 탄생한 것이 바로 가상 DOM
가상DOM
- 실제 브라우저의 DOM이 아닌 리액트가 관리하는 가상의 DOM
- 웹페이지가 표시해야 할 DOM을 일단 메모리에 저장하고 리액트가 실제 변경에 대한 준비가 완료됐을 때 실제 브라우저의 DOM에 반영함
- 이렇게 DOM 계산을 브라우저가 아닌 메모리에서 계산하는 과정을 한 번 거치게 된다면 실제로는 여러 번 발생했을 렌더링 과정을 최소화할 수 있음
리액트 파이버(React Fiber)
- 가상 DOM과 렌더링 과정 최적화를 가능하게 해주는 것
- 리액트에서 관리하는 평범한 자바스크립트 객체
- 파이버의 구성 요소
- Fiber 노드 : 파이버 알고리즘이 사용하는 데이터 구조
- 알고리즘 : 기존의 스택 기반 알고리즘과 다른 재조정 알고리즘, 비동기적이고 우선순위 기반으로 작업 처리
- 스케줄러 : 작업의 우선순위를 관리하고 중요한 작업을 먼저 처리함. 작업을 작은 단위로 나누어 비동기적으로 처리할 수 있도록 함
- 파이버는 파이버 재조정자가 관리
- 파이버 재조정자 : 가상 DOM과 실제 DOM을 비교해 변경 사항을 수집하며, 이 둘 사이에 차이가 있으면 변경에 관련된 정보를 가지고 있는 파이버를 기준으로 화면에 렌더링을 요청하는 역할
- 리액트 웹 애플리케이션에서 발생하는 애니메이션, 레이아웃, 그리고 사용자 인터렉션에 올바른 결과물을 만드는 반응성 문제를 해결하는 것
- 파이버의 역할
- 작업을 작은 단위로 분할하고 쪼갠 다음, 우선순위를 매김
- 이러한 작업을 일시 중단하고 나중에 다시 시작 가능
- 이전에 했던 작업을 다시 재사용하거나 필요하지 않은 경우 폐기할 수 있음
- 이러한 모든 과정이 비동기로 일어남 => 기존 렌더링 스택의 비효율성을 타파하기 위함
- 파이버는 하나의 element에 하나가 생성되는 1:1 관계를 가짐
- 파이버는 state가 변경되거나 생명주기 메서드가 실행되거나 DOM의 변경이 필요한 시점 등에 실행됨
리액트의 동작 단계
- 렌더 단계 : 리액트는 사용자에게 노출되지 않는 모든 비동기 작업을 수행함. 파이버의 작업, 우선순위를 지정할 수 있고, 우선순위가 높은 작업이 있다면 중단시키고 나중에 재개할 수 있음
- 커밋 단계 : DOM에 실제 변경 사항을 반영하기 위한 작업인 commitWork()가 실행됨. 이는 동기식으로 일어나고 중단될 수도 없음
파이버 트리
- 리액트 내부에서 두 개가 존재함 => 더블 버퍼링을 위함(커밋 단계)
- 현재 모습을 담은 파이버 트리
- 작업 중인 상태를 나타내는 workInProgress 트리
더블 버퍼링
- 리액트 파이버의 작업이 끝나면 리액트는 단순히 포인터만 변경해 workInProgress 트리를 현재 트리로 바꿈
- 먼저 현재 UI 렌더링을 위해 존재하는 트리인 current를 기준으로 모든 작업이 시작됨
- 만약 업데이트가 발생하면 파이버는 리액트에서 새로 받은 데이터로 새로운 workInProgress 트리를 빌드하기 시작함
- 빌드 작업이 끝나면 다음 렌더링에 이 트리를 사용함
- workInProgress 트리가 UI에 최종적으로 렌더링되어 반영이 완료되면 current가 이 workInProgress로 변경됨
파이버의 작업 순서
- 일반적인 파이버 노드의 생성 흐름
- 리액트는 beginWork() 함수를 실행해 파이버 작업을 수행하는데, 더 이상 자식이 없는 파이버를 만날 때까지 트리 형식으로 시작됨
- 위의 작업이 끝나면 그 다음 completeWork() 함수를 실행해 파이버 작업을 완료함
- 형제가 있다면 형제로 넘어감
- 2,3번이 모두 완료되면 return으로 돌아가 자신의 작업이 완료됐음을 알림
파이버와 가상 DOM
- 파이버는 리액트 컴포넌트에 대한 정보를 1:1로 가지고 있는 것
- 파이버는 리액트 아키텍처 내부에서 비동기로 이루어짐
- 실제 브라우저의 구조인 DOM에 반영하는 것은 동기적으로 일어나야 함
- 작업을 미리 가상 즉, 메모리 상에서 먼저 수행해 최종적인 결과물만 실제 DOM에 적용하는 것이 가상 DOM
- 개발자가 직접 DOM을 수동으로 하나하나 변경해야 한다면 어떤 값이 바뀌었는지, 또 그 값에 따라 어떠한 값이 변경됐고 이와 관련된 것들이 무엇이었는지 파악하기 어려움
- 이러한 어려움을 리액트 내부의 파이버와 재조정자가 내부적인 알고리즘을 통해 관리해 줌으로써 대규모 웹 애플리케이션을 효율적으로 유지보수하고 관리할 수 있게 됨
'FE > 리뷰' 카테고리의 다른 글
[모던 리액트 딥다이브] 2.4장 렌더링 (0) | 2024.07.13 |
---|---|
[모던 리액트 딥다이브] 2.3장 클래스 컴포넌트와 함수 컴포넌트 (0) | 2024.07.07 |
[모던 리액트 딥다이브] 2.1장 JSX (0) | 2024.07.07 |
[모던 리액트 딥다이브] 1.7장 타입스크립트 (0) | 2024.06.29 |
[모던 리액트 딥다이브] 1.6장 리액트에서 자주 사용하는 자바스크립트 문법 (0) | 2024.06.27 |