리액트 개발을 하던 중 useLayoutEffect를 마주쳤다.
이름만 봤을 땐 useEffect와 비슷해 보이는데 Layout이 무엇인가 궁금해졌다.
먼저, 브라우저 렌더링 과정에 대해 정리해 보자.

1. 브라우저가 서버에 필요한 리소스를 요청한다.(Navigation)
2. HTML파일과 CSS파일을 파싱 하여 각각의 DOM트리와 CSSOM 트리를 만든다(Parsing)
3. 두 트리를 결합하여 렌더 트리를 만들고(Render Tree)
4. 렌더 트리에서 각 요소의 위치와 크기를 계산한다(Layout)
5. 계산된 값을 바탕으로 요소들의 스타일을 적용하고, 픽셀로 변환하여 화면에 그림을 그린다.(Painting)
6. 페인트 단계에서 생성된 레이어들을 합성하여 실제 화면에 나타낸다.(Composite)
useEffect
useEffect는 컴포넌트의 rendering과 painting이 완료된 후 비동기적으로 실행된다.
즉, DOM이 그려지고 난 후에 상태값에 따라 다시 렌더링이 되기 때문에 useEffect에 DOM에 영향을 주는 코드가 있으면 화면의 깜빡임이 발생한다.

useLayoutEffect
useLayoutEffect는 컴포넌트의 rendering이 완료되고 동기적으로 실행된다.
즉, paint가 되기 전에 실행되기 때문에 DOM에 영향을 주는 코드가 있어도 화면의 깜빡임은 발생하지 않는다.

두 훅의 사용법은 완전히 동일하다.
useEffect(() => {
...
}, [dependancy]);
useLayoutEffect(() => {
...
}, [dependancy]);
대부분의 경우 useEffect를 사용하지만, 컴포넌트가 표시될 때 깜빡거리는 현상을 최소화 하기 위해 useLayoutEffect를 사용할 수 있다.
하지만 useLayoutEffect는 실행이 완료될 때까지 UI 업데이트가 멈추기 때문에 훅 내부에 복잡한 코드를 넣게 될 경우 성능에 영향을 미치게 되어 주의하여 사용해야 한다.
참고
https://web.dev/learn/performance/understanding-the-critical-path?hl=ko