잘못된 내용이 있다면 알려주시면 감사하겠습니다.
이전 글: https://so-tired.tistory.com/336
서론
요즘 HTML + CSS + Javascript로 순수하게 프론트엔드 개발을 하는 사람은 드물 것이다.
그 대신 라이브러리나 프레임워크를 이용한다. (차후, 그냥 통합하여 프레임워크라 하겠다.)
왜? 어떤 이유가 있어서일까?
그 이유로는 생산성 증대, 대규모 프로젝트 관리 용이, 성능 등등.. 여러 가지 일 것이다.
그런데 프레임워크를 써서 개발하는게 순수하게 Vanilla JS로 개발하는 것보다 좋을까?
이번엔 프레임워크가 렌더링에 주는 이점에 대해서 한 번 알아보자.
프레임워크가 렌더링에 주는 이점
DOM은 동적 UI 변경에 최적화 되어있지 않다
우리는 프론트 개발을 하면서 DOM을 조회하기도 하고 조작하기도 한다.
- 조회: getElementById, textContent, contains...
- 조작: appendChild, removeChild, innerHTML...
DOM은 느리지 않다. 브라우저의 성능이 발전함에 따라서 DOM 트리가 바뀌지 않는 선에서의 조회와 조작은 빠르게 처리된다.
다만, 우리가 DOM 트리를 조작하는 행위가 일어나면 브라우저는 렌더 트리를 재생성하고 리플로우, 리페인트 과정을 거쳐야 하기 때문에 일반적인 작업 대비 느려진다.
그래서 우리는 가급적 DOM 조작 행위를 최적화할 필요가 있다.
아래 예시를 봐보자.
많은 조작은 DOM을 저하시킨다
아래 두 코드는 3000번 순회하면서 ul에 li를 삽입하는 동일한 뷰를 보여주는 코드이다.
두 코드는 뷰는 동일하지만 동작방식에 차이가 있는데 아래와 같다.
- 1번 코드는 DOM을 3000번 수정한다.
- 2번 코드는 DOM을 1번 수정한다.
위의 두 코드에 대해서 performance로 onClick이 동작하는 소요시간을 측정해 보면 다음과 같은 결과를 볼 수 있다.
이러한 결과는 잦은 DOM의 조작은 웹 퍼포먼스를 저하 시킨다는 점을 잘 보여준다.
그래서 DOM을 직접 조작해야 할 때에는 동시에 발생한 이벤트들을 모아서 DOM 조작을 최소한으로 가져가는 것이 더 나은 성능을 기대할 수 있다.
프레임워크를 쓴다면?
React와 Vue는 위에서 말한 문제를 효과적으로 해결하기 위해 자체적인 변경 감지 및 렌더링 방식을 지니고 있다.
이처럼 프레임워크들은 변경감지와 비교를 통해 렌더링 과정을 최적화하기 위해서 노력한다.
그럼 무조건적으로 프레임워크를 쓰면 DOM 조작에 있어서 더 좋은 성능을 보일까?
그렇지만은 않다.
간단한 DOM 조작이나 적은 요소의 업데이트를 할 때에는 Vanilla JS 방식이 더 나을 수도 있다.
왜냐, 프레임워크를 사용하면 자체적인 렌더링 과정 + 기존 렌더링 과정 순서대로 진행되기 때문에 오히려 성능을 저하시킬 수도 있다.
프레임워크를 쓰면 렌더링에 좋을까?
그럼에도 불구하고 프레임워크를 쓰면 대부분의 개발환경에서 더 나은 렌더링 성능을 보일 것이다.
렌더링 과정에서 그 이유는 2가지이다.
1. DOM의 동적 UI 변경 과정에 대한 최적화를 자동으로 해준다.
2. 자체적인 렌더링 과정이 불필요한 리플로우, 리페인트 과정을 줄여주기 때문이다.
이에 대해서 React를 기반으로 알아보자.
사례
아래 두 코드는 이전과 동일한 3000번 순회하면서 ul에 li를 삽입하는 동일한 뷰를 보여주는 코드이다.
다만 다른 점이 있다면, 왼쪽은 React로 오른쪽은 JS로 작성했다.
아래 두 이미지는 위 코드에 대한 1차 렌더링 결과이다.
두 렌더링 시간을 비교해 보면 React가 조금 더 빠르지만 큰 차이는 나지 않는다.
하지만 (다시 버튼을 눌러 동일한 로직을 실행시킨) 2차 렌더링 결과를 보면, React가 압도적으로 빠르다.
두 코드의 1차 렌더링 시간을 비교해 보면 거의 유사한데, 2차의 경우 React를 사용했을 때는 자체적인 렌더링 과정으로 인해 불필요한 리플로우, 리페인트 과정이 줄어들었다는 것을 유추해 볼 수 있다.
그럼 만약 setList를 3000번 일으키면 이전과 같이 성능이 저하될까?
그렇지 않다.
어떻게 이런 마법 같은 일이 일어날까?
React는 어떤 방식을 통해서 이런 일을 가능하게 하는지 React의 배칭을 잘 살펴보자.
Batching (배칭, 배치 처리)
꼭꼭 읽어 보세요!! https://ko.react.dev/learn/queueing-a-series-of-state-updates
React는 렌더링을 최적화하기 위해서 Batching 이라는 방법을 쓴다.
이러한 방법을 사용하는 이유는 단 기간에 일어나는 상태변화를 매번 렌더링 시키지 않고, 일괄 처리함으로써 성능을 최적화하기 위해서이다.
Batching에 대해서 React 개발자는 다음과 같이 얘기했다.
Batching is when React groups multiple state updates into a single re-render for better performance.
Batching은 더 나은 성능을 위해 (같은 이벤트 루프 내에서 발생하는) 여러 상태 업데이트를 하나의 리렌더링으로 묶는 것이다.
위 내용에 대해서 잘 이해가 가지 않는다면 아래 코드를 보자.
해당 코드는 문제가 있어 보이지만 Batchcing에 대해서 잘 나타내고 있다.
setCount가 실행될 때마다 count가 변경되어 useEffect 내부의 console.log가 3번 찍혀야 할 것 같지만, console.log는 3으로 딱 한 번만 찍혔다.
이는 setCount에 대한 처리를 React 내부의 Update Queue에 저장했다가 배치 처리 했기 때문이다.
왜 이런 처리 방식을 택했을까?
이는 음식점에서 주문받는 웨이터를 생각해 볼 수 있다.
웨이터는 첫 번째 요리를 말하자마자 주방으로 달려가지 않는다.
대신 주문이 끝날 때까지 기다렸다가 주문을 변경하고, 심지어 테이블에 있는 다른 사람의 주문도 받는다.
setState가 비동기로 동작하는 이유가 바로 여기에 있다.
일정 기간이 끝날 때까지 setState를 실행하지 않고 모아둔다.
Batching은 어떤 단위로 일어날까?
Batching은 같은 실행 컨텍스트 단위로 일어난다.
그럼 아래 코드는 어떻게 동작할지, Batching이 몇 번 동작할지 생각해 보자.
Batching의 실행 횟수를 예측하기 위해선 이벤트 루프와 실행 컨텍스트에 대한 개념이 우선시되어야 한다.
위 handleClick에서는 await로 인해 handleClick의 실행 컨텍스트가 중단되었다 보니 두 차례에 걸쳐서 Batching이 일어난 것이다.
만약, setTimeout이 await 없이 Promise에 담기지 않고 실행되었다면?
한 번의 Batching만으로 충분했을 것이다.
이런 Batching 과정에 대해서 잘 이해하고 있다면 불필요한 렌더링과 useEffect로 인한 에러를 방지하는데 도움이 될 것이다.
참고
React v18.0 – React
The library for web and native user interfaces
react.dev
React에서 상태들을 한번에 묶어서 렌더링을 시키는 기능 - 자동 배치
약 한 달전 데브코스 멘토님으로부터 리액트는 상태 변화같은게 실시간으로 적용되고 작동할까요? 라는 질문을 받았는데 그때 저는 대답을 하지 못했던 기억이 있었습니다. 물론 아닌것을 알고
velog.io
리액트 배칭(Batching)의 모든 것 | 요즘IT
아직까지 많은 리액트 개발자가 오해하고 있는 부분이 있는데요. 바로 자동 배칭의 정확한 개념을 모른다는 점입니다. 이번 글에서는 리액트 ‘배칭(Batching)’에 관한 전반적인 소개와 배칭과
yozm.wishket.com
[React] Batching을 활용한 렌더링 최적화
React 18(22.3.29)에서 Batching이 더욱 강화되었다. Batching은 React에서 굉장히 중요한 개념이며, 최적화에 크게 기여하고 있다. 하지만 생각보다 Batching은 초보 리액트 개발자에게 널리 알려지지는 않은
happysisyphe.tistory.com
'개발' 카테고리의 다른 글
1. 브라우저 렌더링 과정 (0) | 2025.03.16 |
---|---|
입력 값이 바뀜에 따라 요청이 계속 보내진다면? (Throttling & Debouncing) (4) | 2025.01.12 |
"NET::ERR_CERT_DATE_INVALID" 에러 & SSL 인증서 재발급 (0) | 2024.09.13 |
내가 생각하는 프로젝트 규모에 따른 프론트 기술스택 선정기준 (0) | 2024.08.24 |
[Webflow] Scroll into view 애니메이션이 한 번 밖에 실행이 안될때 (0) | 2024.07.13 |