PromleeBlog
sitemapaboutMe

posting thumbnail
React 렌더링과 실행 환경 - React, 알고 쓰자 0주차
React Rendering & Runtime - React Explained Week 0

📅

🚀

들어가기 전에🔗

React로 작성한 코드가 실제로 어떻게 웹 브라우저 화면에 그려지는지 궁금하지 않으신가요? useState가 상태를 바꾸면 화면이 마법처럼 바뀌는 것 같지만, 그 뒤에는 웹 브라우저와 JavaScript 엔진, 그리고 React 라이브러리가 긴밀하게 협력하는 정교한 과정이 숨어있습니다.
이번 0주차에서는 React 코드를 작성하는 것을 넘어, 그 코드가 브라우저라는 무대 위에서 어떻게 생명을 얻고 사용자 눈앞에 나타나는지에 대한 근본적인 원리를 탐구해 보려 합니다.
브라우저의 렌더링 과정, JavaScript가 동작하는 방식, 그리고 다양한 웹 렌더링 모델들을 이해하는 것은 React를 더욱 깊이 있고 효과적으로 사용하는 튼튼한 기반이 될 것입니다.

🚀

React 코드가 브라우저를 만나기까지🔗

우리가 작성하는 React 코드는 주로 JSX 문법을 포함한 JavaScript 파일입니다. 하지만 웹 브라우저는 JSX를 직접 이해하지 못합니다. 그래서 브라우저가 이해할 수 있는 순수한 HTML, CSS, JavaScript 형태로 변환하는 과정이 필요합니다.
빌드(Build) 과정
: 개발 중에 작성한 코드(React 컴포넌트, JSX, 최신 JavaScript 문법, CSS 등)를 실제 브라우저에서 실행 가능한 정적인 파일들(HTML, CSS, JavaScript 번들)로 변환하는 작업을 말합니다.
도구들
: 이 과정에서 주로
바벨(Babel)
같은 트랜스파일러가 JSX와 최신 JavaScript 문법을 구형 브라우저에서도 호환되는 코드로 변환하고,
웹팩(Webpack)
이나
Parcel
같은 모듈 번들러가 여러 개의 JavaScript 파일과 의존성들을 하나 또는 몇 개의 파일로 묶어주는 역할을 합니다. (Create React App이나 Vite 같은 도구들이 내부적으로 이런 설정들을 편리하게 제공해주죠.)
이렇게 빌드된 결과물(주로 index.html과 여러 개의 .js, .css 파일)이 웹 서버를 통해 사용자 브라우저로 전달되면, 비로소 화면을 그리는 시발점이 됩니다.
변환 과정
변환 과정

🚀

브라우저는 화면을 어떻게 그릴까? (렌더링 파이프라인)🔗

브라우저가 HTML, CSS, JavaScript 파일을 받아서 우리 눈에 보이는 화면(픽셀)으로 만들기까지는 정해진 단계들이 있습니다.
이를
렌더링 파이프라인(Rendering Pipeline)
또는
Critical Rendering Path
라고 부릅니다. 이 과정을 이해하는 것은 웹 성능 최적화와 React의 렌더링 방식을 이해하는 데 매우 중요합니다.

1. HTML 파싱 & DOM 트리 생성🔗

브라우저는 가장 먼저 HTML 파일을 읽고 해석(파싱, Parsing)하여
DOM(Document Object Model) 트리
를 만듭니다. DOM 트리는 HTML 문서의 구조와 내용을 객체 모델로 표현한 것입니다. <html>, <body>, <div>, <p> 같은 각 태그들이 트리 구조의 노드(Node)로 변환되어 부모-자식 관계를 형성합니다.
<!DOCTYPE html>
<html>
  <head><title>My Page</title></head>
  <body>
    <div>
      <h1>Hello</h1>
      <p>World</p>
    </div>
  </body>
</html>
위 HTML은 아래와 같은 DOM 트리 구조로 변환될 수 있습니다.
DOM 트리
DOM 트리

2. CSS 파싱 & CSSOM 트리 생성🔗

HTML 파싱 중에 <link> 태그나 <style> 태그를 만나면 CSS 파싱이 시작됩니다.
브라우저는 CSS 코드를 해석하여
CSSOM(CSS Object Model) 트리
를 만듭니다. CSSOM 트리는 DOM 요소들에 적용될 스타일 규칙들을 트리 구조로 표현한 것입니다. 여기에는 각 요소의 색상, 크기, 위치 등 스타일 정보가 담겨 있습니다.

3. 렌더 트리(Render Tree) 생성🔗

DOM 트리와 CSSOM 트리가 만들어지면, 브라우저는 이 두 트리를 결합하여
렌더 트리
를 생성합니다.
렌더 트리는 화면에
실제로 표시될 요소
들만 포함하며, 각 요소의 스타일 정보도 함께 가지고 있습니다. 예를 들어, display: none; 스타일이 적용된 요소는 DOM 트리에는 존재하지만 화면에 표시되지 않으므로 렌더 트리에는 포함되지 않습니다. <head> 태그처럼 시각적으로 표현되지 않는 요소들도 제외됩니다.
[DOM 트리]
    ├── <html>
    │   ├── <head>
    │   └── <body>
    │       ├── <div>
    │       ├── <span>
    │       └── <p>

[CSSOM 트리]
    ├── {div { display: block; }}
    ├── {span { display: none; }}
    └── {p { display: block; }}

[렌더 트리]
    ├── <div>
    └── <p>
렌더 트리는 DOM 트리와 CSSOM 트리를 결합하여 화면에 실제로 그려질 요소들만 포함합니다. 즉, 렌더 트리는 DOM과 CSSOM의 조합으로 만들어진 최종적인 시각적 표현을 위한 데이터 구조입니다.
렌더 트리가 되는 과정
렌더 트리가 되는 과정

4. 레이아웃(Layout) 또는 리플로우(Reflow)🔗

렌더 트리가 생성되면, 브라우저는 각 요소들이 화면의 어디에, 어떤 크기로 배치될지 계산하는
레이아웃
단계를 진행합니다. 각 노드의 정확한 위치와 크기를 결정하는 과정이죠.
퍼센트(%) 값이나 vh, vw 같은 상대적인 단위들은 이 단계에서 실제 픽셀 값으로 변환됩니다.
만약 요소의 크기나 위치가 변경되거나, DOM 구조가 변경되어 레이아웃에 영향을 주면 이 과정이 다시 발생하는데, 이를
리플로우(Reflow)
라고 부릅니다. 리플로우는 계산 비용이 비싼 작업 중 하나입니다.

5. 페인팅(Painting) 또는 리페인트(Repaint)🔗

레이아웃 단계에서 계산된 정보를 바탕으로, 브라우저는 각 요소들을 화면의 실제 픽셀로 그리는
페인팅
단계를 수행합니다.
텍스트, 색상, 이미지, 그림자 등을 화면에 채워나가는 과정이죠.
만약 배경색이나 글자색 변경처럼 레이아웃에는 영향을 주지 않지만 화면 모양만 바뀌는 경우, 레이아웃 단계를 건너뛰고 페인팅만 다시 발생하는데 이를
리페인트(Repaint)
라고 합니다.
Q:"브라우저 렌더링 과정을 설명해주세요."
A: DOM/CSSOM 생성 -> 렌더 트리 생성 -> 레이아웃 -> 페인팅 순서와 각 단계의 역할을 명확히 설명. 성능 관점에서 리플로우와 리페인트의 차이를 아는 것도 좋습니다.

🚀

React의 첫 렌더링🔗

자, 그럼 React 애플리케이션의 첫 렌더링은 이 브라우저 렌더링 파이프라인과 어떻게 연결될까요?
  1. JavaScript 실행 및 Virtual DOM 생성
    브라우저가 빌드된 JavaScript 번들 파일을 로드하고 실행합니다. React 코드가 실행되면서, 컴포넌트 함수들이 호출되고 JSX는 React.createElement() 호출로 변환됩니다.
    이 과정을 통해 React는 메모리 상에 실제 DOM 구조를 본뜬 가벼운 객체 트리, 즉
    Virtual DOM
    을 생성합니다.
  2. 실제 DOM 노드 생성 및 삽입
    첫 렌더링 시에는 비교할 이전 Virtual DOM이 없으므로, React는 생성된 Virtual DOM 정보를 바탕으로 실제 DOM 노드들을 만듭니다.
    그리고 이 노드들을 index.html 파일에 있는 루트 DOM 노드(보통 <div id="root"></div>)의 자식으로 삽입합니다.
  3. 브라우저 렌더링 파이프라인 촉발
    이렇게 실제 DOM에 변경(노드 삽입)이 발생하면, 브라우저는 이를 감지하고 위에서 설명한 렌더링 파이프라인(레이아웃 -> 페인팅)을 실행하여 변경된 내용을 화면에 그립니다.
즉, React는 직접 픽셀을 그리는 것이 아니라, DOM을 효율적으로 관리하고 변경하는 역할을 합니다.
실제 화면에 그리는 것은 여전히 브라우저의 몫이죠. React의 역할은 브라우저가 일을 더 효율적으로 할 수 있도록 돕는 것이라고 생각할 수 있습니다.
이후 업데이트 과정에서는 Virtual DOM 비교(재조정)를 통해 최소한의 DOM 변경만 수행하여 성능을 최적화합니다. 이 내용은 다음 시간에 더 자세히 다룰 예정입니다 :)

🚀

JavaScript는 어떻게 동작할까?🔗

React는 JavaScript 라이브러리이므로, JavaScript가 어떻게 동작하는지 이해하는 것도 중요합니다.
특히 JavaScript의
비동기 처리 방식
은 React의 이벤트 처리나 상태 업데이트와 밀접한 관련이 있습니다.

싱글 스레드와 이벤트 루프🔗

JavaScript는 기본적으로
싱글 스레드(Single Thread)
기반 언어입니다.
즉, 한 번에 하나의 작업만 처리할 수 있습니다. 그런데 웹 페이지에서는 사용자 클릭에 반응하면서 동시에 네트워크 요청을 보내고 애니메이션도 보여줘야 합니다. 어떻게 이게 가능할까요?
바로 JavaScript 실행 환경(브라우저나 Node.js)이 제공하는
이벤트 루프(Event Loop)
덕분입니다.
이벤트 루프 다이어그램
이벤트 루프 다이어그램
React에서 버튼 클릭 이벤트 핸들러가 실행되거나, setState가 호출되어 상태 업데이트가 예약되는 것은 모두 이 이벤트 루프 메커니즘 위에서 동작합니다.
예를 들어 setState는 즉시 상태를 바꾸고 리렌더링하는 것이 아니라, 업데이트 작업을 예약하고 이벤트 루프를 통해 적절한 시점에 처리될 수 있습니다 (곧 배울 배치 처리와도 관련이 깊습니다).
Q:"이벤트 루프에 대해 설명해주세요." or "JavaScript는 싱글 스레드인데 어떻게 비동기 처리가 가능한가요?"
A: 콜 스택, 힙, 태스크 큐, 이벤트 루프의 역할과 상호작용을 설명.

🚀

다양한 렌더링 방식들 (CSR, SSR, SSG)🔗

웹 페이지를 사용자에게 보여주는 방식에는 여러 가지 렌더링 모델이 있습니다. React는 다양한 모델과 함께 사용될 수 있습니다.

Client-Side Rendering (CSR)🔗

Server-Side Rendering (SSR)🔗

Static Site Generation (SSG)🔗

Q: "CSR, SSR, SSG의 차이점과 장단점을 설명해주세요."
A: 각 방식의 동작 원리와 대표적인 장단점, 그리고 언제 사용하는 것이 적합한지 설명

🚀

결론🔗

오늘은 React 코드를 작성하는 것에서 한 걸음 더 나아가, 우리가 만든 애플리케이션이 웹이라는 큰 생태계 속에서 어떻게 동작하는지에 대한 기초를 다졌습니다.
이러한 웹의 기본적인 동작 원리를 이해하는 것은 단순히 React 문법을 아는 것 이상으로 중요합니다. 성능 문제를 진단하고, 더 나은 사용자 경험을 제공하며, 기술적인 의사결정을 내리는 데 큰 도움이 될 것입니다.
다음 1일차부터는 오늘 잠깐 언급했던 React의 핵심 동작 원리, 즉 Virtual DOM과 재조정(Reconciliation), 그리고 Fiber 아키텍처에 대해 본격적으로 파헤쳐 보겠습니다.

참고🔗