2 분 소요

리액트 로고

이 글을 쓰는 계기,,

지금껏 리액트를 공부해오면서
입에서 “렌더링”이라는 단어를 셀 수도 없이 많이 뱉었다.
하지만, useEffect와 useLayoutEffect에 대해서 알아보면서
도대체 render와 paint의 차이는 뭐야? 어? render의 정확한 의미가 뭐지?
그냥 눈에 보이게끔 하는 게 render 아니야? 하면서 문득
아 공부를 잘못하고 있었구나 하는게 느껴졌다.
그래서 React 공식 문서를 토대로 정리를 해보았다.

그래서 렌더링이 뭔데 ?

“Rendering” is React calling your components.
- React 공식 문서

리액트 공식문서에서 설명하기를, 렌더링은 컴포넌트의 호출이라고 한다.
컴포넌트가 화면에 나타나기 전, 모든 컴포넌트들은 반드시 React에 의해 render되어야 한다.

만약 우리가 식당이라고 가정을 해보자.

렌더링 과정

  1. 웨이터는 우리의 주문을 받아 주방에 전달하고
    (Trigger a Render)
  2. 주방에서는 음식을 만들어 내어주고
    (Rendering the Component)
  3. 웨이터는 그 음식을 받아 우리에게 서빙을 한다.
    (Commiting to the DOM)

이 3가지의 Step이 React 공식문서에서 설명하는 Render & Commit이라고 한다.

더 자세히 들어가보자.

Render & Commit 3Steps

1. Trigger a Render

컴포넌트의 렌더링이 발생하는 데에는 2가지 이유가 있다 :

  1. 컴포넌트의 최초 렌더링
  2. 컴포넌트(혹은 부모 컴포넌트)의 상태 업데이트

1-1. Initial Render (컴포넌트 최초 렌더링)

React app을 실행할 때, 우리는 최초의 렌더링을 일으켜야 한다.
createRoot를 호출한 다음, component와 함께 render메서드를 호출하여 수행한다.

// index.js
import { createRoot } from "react";
import App from "./App.js";

const root = createRoot(document.getElementbyId("root"));
root.render(<App />);

1-2 Re-renders when state updates
(상태 변경에 의한 리렌더링)

컴포넌트 최초의 렌더링이 일어나고 난 후, setfunction을 사용한
상태(state) 업데이트를 통해, 추가적인 렌더링 일으킬 수 있다.
컴포넌트 상태의 업데이트는 자동으로 해당 컴포넌트를 렌더링 대기열에 추가하게 된다.

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <>
      <button onClick={setCount(count - 1)}>-</button>
      <span>{count}</span>
      <button onClick={setCount(count + 1)}>+</button>
    </>
  );
}

2. React renders your components

render를 발생시키고 난 후, React는 컴포넌트에게 화면에 띄워야 할 것이 무엇인지 찾아오도록 요청한다.
“Rendering” is React calling your components.
직역하자면, 렌더링은 컴포넌트를 호출하는 React를 의미한다.

  • 최초 렌더링 시, React는 root 컴포넌트를 호출한다.
  • 리렌더링 시, React는 상태 업데이트를 통해 render를 발생시킨
    컴포넌트를 호출한다.

리렌더링 과정

이 과정은 재귀적이다. 만약 렌더링된 컴포넌트가 다른 컴포넌트를 반환할 때, React는 컴포넌트를 다음 컴포넌트를 render한다.
이 과정이 더 이상 중첩된 컴포넌트가 없을 때까지 반복된다. 그 후 React는 화면에 띄워야 할 것이 무엇인지 정확히 인지한다.

3. Commiting to the DOM

컴포넌트 렌더링 후, React는 DOM을 수정한다.

  • 최초 렌더링 시, React는 appendChild() DOM API를 사용하여 모든 DOM 노드들을 화면에 출력한다.
  • 리렌더링 시, React는 DOM이 최신 렌더링의 출력과 일치하도록 렌더링 시 계산된 최소한의 필수 작업을 진행한다.

리액트는 변경 사항이 있는 DOM노드들만 바꾼다.

export default function Clock({ time }) {
  return (
    <>
      <h1>{time}</h1>
      <input />
    </>
  );
}

위 코드에서 time의 변경에 따라 h1의 컨텐츠는 업데이트 되지만,
React는 input태그는 건드리지 않기 때문에, input 태그에는 리렌더링이 발생하지 않는다고 한다.

Epilogue: Browser Paint

렌더링과 DOM요소 업데이트가 끝나고 난 후, 브라우저는 화면을 repaint 한다. 우리에겐 repaint를 포함하여 화면이 출력되는 모든 과정을 “browser rendering”이라고 잘 알려져 있지만, React에서는 혼돈을 막기 위해 “painting” 이라고 명명하였다.

Conclusion

  1. Render = 컴포넌트 호출
  2. Commit = DOM에 DOM node들을 적용
  3. Painting = 브라우저에 의한 화면 출력

➡️ Render와 Commit, Painting은 전부 다 다른 개념이다.

댓글남기기