-
[React] JSX, 가상 dom과 리액트 파이버SPA/React.js 2024. 10. 19. 19:27
금주부터 React Deep-dive 스터디를 진행하기로 했다.
리액트의 가장 큰 특징인 JSX와 가상 DOM, 리액트 파이버부터 깊게 알아가보자.
1. JSX란?
JSX(Javascript XML)는 리액트에서 자바스크립트 코드와 HTML 구조를 결합한 문법으로,
자바스크립트 파일 내에서 HTML과 유사한 문법을 사용할 수 있게 해준다.
JSX는 브라우저가 직접 이해할 수 있는 형식은 아니지만 리액트가 이를 자바스크립트 코드로 변환해서 실행한다.
이를 통해 개발자들이 좀 더 직관적으로 UI를 구성하고 관리할 수 있게 한다.
(1) JSX의 특징
(1-1) HTML과 유사한 문법
JSX는 HTML과 유사한 문법으로 작성함으로써 컴포넌트의 렌더링 로직을 좀 더 직관적으로 작성할 수 있고 이를 통해 UI와 관련된 코드를 시각적으로 더 명확하게 구분할 수 있다.
const element = <h1>Hello, World!</h1>;
위 코드를 브라우저가 직접 이해할 수 없으므로 내부적으로 Babel과 같은 도구가 아래와 같이 자바스크립트 함수 호출로 변환한다.
const element = React.createElement('h1', null, 'Hello, World!');
(1-2) Javascript 표현식 사용 가능
JSX 안에서 자바스크립트 표현식을 중괄호({ })로 감싸서 사용할 수 있다.
이를 통해 HTML 템플릿 내에서 자바스크립트 변수를 삽입하거나 동적으로 값을 변경할 수 있다.
const name = "KimBoolean"; const element = <h1>Hello, {name}!</h1>;
(1-3) DOM 요소와 React 컴포넌트 구분
JSX에서는 소문자로 시작하는 요소는 DOM 요소로 인식되고,
대문자로 시작하는 것은 React 컴포넌트로 인식된다.
- DOM 요소: <div>, <span>, <h1> 등
- React 컴포넌트: <MyComponent /> 등
(1-4) JSX 속성
JSX에서 속성을 지정할 때는 자바스크립트의 객체와 유사한 형태로 전달한다.
class 이름은 className 속성으로 사용하고 스타일은 style 속성에 객체 형태로 전달한다.
const element = <div className="container" style={{ color: 'red' }}>Hello</div>;
(2) JSX의 장점
(1-1) 가독성 향상
HTML과 유사한 문법을 사용하기에 UI의 구조가 직관적으로 보여 UI 설계에 용이하다.
(1-2) 자바스크립트와 통합
JSX는 자바스크립트 내에서 사용할 수 있으므로 동적 UI를 쉽게 구성할 수 있다.
자바스크립트 표현식을 통해 상태 관리, 조건부 렌더링 등과 자연스럽게 결합된다.
2. DOM이란?
DOM은 Document Object Model의 줄임말로,
웹 페이지 또는 웹 앱에 표시되는 HTML 요소들의 구조화된 표현 즉, 애플리케이션의 전체 UI를 나타낸다.
그러나 DOM이 업데이트될 때마다 페이지의 UI가 업데이트되기 위해 업데이트해야 하는 항목 외에도 해당 페이지에 있는 모든 요소까지 다시 렌더링되어야 한다는 게 단점이다.
그로 인해 CSS를 다시 계산하고 레이아웃을 변경하는 등의 과정을 통해 성능에도 영향을 미치게 되는 것이다.
리액트가 이를 해결하기 위해 가상 DOM을 제안했다.
3. 가상 DOM이란?
Virtual DOM으로, UI의 가상 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리를 통해 실제 DOM과 동기화시켜준다.
실제 DOM을 조작하는 것은 실제 화면에 그려내는 과정이 필요하기에 느리지만
가상 DOM을 조작하는 것은 그렇지 않기에 빠르게 조작할 수 있다.
그로 인해 애플리케이션의 상태에 변화가 있으면 가상 DOM은 실제 DOM보다 먼저 업데이트된다.
가상 DOM의 처리 방식에 대해 잘 설명한 영상이 있어 첨부한다.
아래 유튜브에서 설명하듯이 가상 DOM은 이전의 가상 DOM 트리와 비교하고 변화를 기록하고 이를 실제 DOM에 반영할 최적의 방법을 찾아 업데이트된 요소들만 페이지에 다시 렌더링한다.
여기서 가상 DOM이 실제 DOM과 동기화된 가상의 UI 표현이 메모리에 유지되는 것을 재조정(Reconciliation)이라고 한다.
재조정은 가상 DOM을 먼저 업데이트한 다음 diffing 알고리즘을 통해 실제 DOM에 대해 효율적이고 최적화된 업데이트를 수행한다.
(1) diffing 알고리즘
Differences Algorithm의 줄임말로, 효율적으로 UI를 업데이트하는 핵심 매커니즘이다.
diffing 알고리즘은 실제 DOM과의 차이점만 찾아내는데 아래와 같은 동작 원리를 갖는다.
- 가상 DOM 생성: 리액트는 컴포넌트의 상태나 props가 변경되면 새로운 가상 DOM을 생성하며 이 가상 DOM은 이전 가상 DOM과 비교된다.
- 변경 사항 비교(Diffing): 리액트는 이전 가상 DOM과 새로운 가상 DOM을 비교하여 두 트리 사이의 차이점을 찾아낸다. 이 비교 작업을 Diffing 과정이라고 하며, 리액트는 여러가지 가정을 바탕으로 성능을 최적화한다.
- 최소한의 실제 DOM 업데이트: 리액트는 Diffing 알고리즘으로 발견된 차이점만 실제 DOM에 반영한다. 이렇게 함으로써 불필요한 DOM 조작을 줄이고 더 나은 성능을 제공한다.
이와 같은 과정을 통해 불필요한 리렌더링을 줄임으로써 변경 사항 발생 시 더 빠르게 대응할 수 있다는 장점이 있다.
4. React Fiber
리액트 파이버(React Fiber)는 가상 DOM에서의 작업을 더 세밀하게 처리하는 리액트의 새로운 조정 알고리즘으로, 리액트 16부터 도입된 아키텍쳐다.
파이버는 가상 DOM과 함께 동작하며 변경 사항을 처리하는 과정을 더 효율적으로 만드는 역할을 한다.
리액트 파이버의 핵심 개념으로는 아래 4가지가 있다.
(1) 단위 작업 처리(Incremental Rendering)
파이버는 큰 작업을 여러 작은 작업으로 나누어 처리한다.
이를 통해 브라우저의 메인 스레드를 차지하지 않고 사용자 상호작용이 부드럽게 유지되도록 한다.
메인 스레드(Main Thread)란?
웹 브라우저에서 HTML, CSS, Javascript 등을 처리하고 사용자 인터페이스를 렌더링하며 사용자의 상호작용을 처리하는 중앙 처리 단위이다.
이 스레드가 바쁘면 애플리케이션의 성능이 저하되거나 사용자의 입력에 대한 반응이 느려질 수 있다.리액트는 파이버를 통해 작업을 조금씩 처리하고 중간에 사용자의 입력이나 애니메이션과 같은 중요한 작업이 발생하면 이를 우선적으로 처리한다.
(2) 협력적 스케줄링(cooperative Scheduling)
리액트 파이버는 작업을 협력적으로 스케줄링하여 UI를 적시에 업데이트할 수 있다.
작업이 너무 오래 걸릴 경우, 이를 일시중지하고 중요한 작업이 있으면 먼저 처리한 후 나중에 다시 재개할 수 있다.
(3) 우선순위 기반 업데이트(Priority-based Rendering)
파이버는 업데이트의 우선순위를 설정할 수 있다.
긴급한 업데이트는 빠르게 처리하고 상대적으로 덜 중요한 업데이트는 나중에 처리할 수 있다.
이를 통해 중요한 작업이 빠르게 반영되도록 돕는다.
(4) 이전 상태로 복귀(Backwards Compatibility)
파이버는 기존 리액트 코드를 깨지 않고 동작한다.
즉, 리액트 파이버는 성능 개선을 위한 내부적인 아키텍처 변화일 뿐, 기존 API나 개발 방식에는 큰 차이가 없다.
5. 가상 DOM과 리액트 파이버의 관계
이렇게 봤을 때 가상 DOM과 리액트 파이버의 경계가 모호하게 느껴지기 쉬운데 핵심은 다음과 같다.
- 가상 DOM은 무엇을 업데이트해야 하는지 결정한다. 상태나 속성 변화에 따른 변경 사항을 계산하고 그 차이를 찾는다.
- 파이버는 그 업데이트를 어떻게, 언제 적용할지를 관리한다. 파이버는 가상 DOM에서 발생한 변경 사항을 우선순위에 따라 조정하고 사용자 상호작용에 영향을 주지 않도록 적절한 시점에 작업을 나눠서 실행한다.
즉, 가상 DOM과 파이버는 각각 어떤 것을 업데이트할지와 업데이트를 어떻게 적용할지를 담당하는 상호보완적인 역할을 한다.
[참고]
리액트의 가상 DOM과 Fiber
리액트의 가상 DOM과 Fiber에 대해 알아봅시다!
velog.io
'SPA > React.js' 카테고리의 다른 글
[React] Hook 정복 도전기_useState, useEffect, useContext, useReducer (0) 2024.11.23 [React] QueryClient로 효과적인 서버 관리하기 (2) 2024.10.04 [React] Suspense로 로딩 쉽게 구현하기 (0) 2024.08.10 [React] useMutation 알아보기_(React Query, TanStack Query) (0) 2024.07.21 [React] Firebase로 게시물 카테고리별로 정렬하기 (0) 2022.11.22