[React] DOM vs Virtual DOM
·
React/이론
DOM 앞서 브라우저의 렌더링 과정을 통해서 Repaint와 Reflow가 브라우저 렌더링 중 리소스를 가장 많이 잡아먹는 연산이라고 배웠다. 일반적인 소개 페이지와 같은 정적인 웹 애플리케이션이라면 DOM이 더 좋은 성능을 나타낸다. 하지만 문제는 복잡한 SPA에서는 DOM 조작이 많이 발생한다는 것이다. Repaint와 Reflow가 빈번하게 발생하는 웹사이트에서는 UI/UX 렌더링에 비교적 많은 리소스를 잡아먹기 때문에 전체적인 프로세스를 비효율적으로 만든다. Virtual DOM Virtual DOM은 Reflow와 Repaint를 줄여서 브라우저 레이아웃 엔진의 성능에 최적화를 시켜준다. 이게 어떻게 가능할까? 먼저 브라우저에 렌더링을 한 후에 Virtual DOM을 하나 만듭니다. 그리고 변화..
[React] 렌더링
·
React/이론
이전에 브라우저의 렌더링이 어떤 방식으로 이루어지는 지 알아봤다 이번에는 React에서의 렌더링을 알아보자! 클래스 컴포넌트에서의 LifeCycle에 대한 이미지를 가지고 왔다. ComponentDidUpdate, DidMount 등등은 우리가 많이 알고 있는 익숙한 것들이다. 하지만 옆에 Render Phase, Commit Phase에 대해서는 특별하게 들어본 적이 없다. React에서의 Render Phase와 Commit Phase가 무엇인지 알아보자 Render Phase 간단하게 말하자면 컴포넌트 함수를 호출해서 React의 Element를 반환하고 새로운 Virtual DOM을 만들어준다. 그리고 최초 렌더링이 아니라면 재조정을 통해서 실제 DOM에서 적용할 변경점을 확인한다. 재조정 ( R..
[React] 브라우저의 렌더링 과정
·
React/이론
브라우저에서는 Reflow와 Repaint 작업을 진행한다. 이 둘은 웹 애플리케이션의 성능을 떨어뜨리는 주된 요인인데, 한번 천천히 알아보자 DOM Tree HTML을 전달 받은 브라우저는 렌더 엔진에서 이를 파싱하고 DOM 노드로 이루어진 트리인 DOM Tree를 만들어낸다. Style Rules 이어서 외부 CSS 파일과 엘리먼트의 inline 스타일을 파싱해서 메모리 상 Style Rules을 생성한다. Render Tree DOM Tree와 Style Rules을 바탕으로 실제 브라우저 화면에 노출되는 노드에 대한 정보를 가진 Render Tree를 만들어준다. 이때 태그나 display 속성이 none인 태그들과 같이 보이지 않는 노드는 Render Tree를 생성할 때 제외하고 생성된다. L..
[React] Context API 사용하기
·
React/실험실
들어가며, Redux와 Context API를 비교하는 글을 작성했었다. 해당 글의 결론에서 Context API를 사용할 때 useState를 사용해서 만든 state를 Context.Provider의 value에 바로 넣을 경우 setState를 사용할 때마다 useContext를 사용하는 모든 자식 컴포넌트가 리렌더링되는 문제가 있었다. 이것을 해결하는 방법을 정리하겠다. Context 상태 나누기 const counterReducer = (state, action) => { switch (action.type) { case "INCREMENT": return { number: state.number + 1, }; case "DECREMENT": return { number: state.number..
[React] Redux vs Context API
·
React/실험실
일반적으로 전역 상태 관리를 위해서는 Redux와 같은 전역 상태 관리 라이브러리를 사용한다. 이때 Context API를 왜 사용하지 말라는 부분을 정리된 글을 많이 봤다. 하지만 이것을 직접 테스트하지 않았기 때문에 이번에 비교를 해보려고 한다. ( 머리로만 이해하는 것과 눈과 손을 함께 사용하는 것 중 후자가 더 좋을 테니 ㅎㅎ ) 작업 Redux 사용하는 패키지는 react-redux, @reduxjs/toolkit 간단한 테스트를 하기 때문에 기본적인 패키지만 사용했다. // /reducer/counter.js import { createSlice } from "@reduxjs/toolkit"; const initialState = { value: 0, }; const counterSlice =..
[React] 제어 컴포넌트 vs 비제어 컴포넌트
·
React/실험실
앞서 useState와 useRef에 대해서 정리를 했었다. [React] useRef 그리고 useState 일반적으로 우리가 상태값을 관리할 때는 useState를 사용한다. 거기에서 state 값이 변경되면 리렌더링이 발생하면서 화면이 새롭게 그려진다. 그런데, 상태값이 변경되더라도 굳이 리렌더링이 필 bum-developer.tistory.com 해당 부분에 대한 보충 내용이지만 좀 더 개념적인 부분이라 따로 작성했다. 제어 컴포넌트 React에 의해서 값이 제어되는 컴포넌트를 말한다. 우리가 자주 사용하는 useState를 사용해서 DOM 요소의 값을 관리하면 제어 컴포넌트이다. const App = () => [ const [value, setValue] = useState(""); const..
[React] useMemo vs useRef
·
React/실험실
최근 성능 최적화에 대해서 공부하던 중 " useMemo와 useRef의 차이가 뭘까? " 에 대해서 궁금증이 생겼다. 둘을 비교하려면 우선 각각 뭔지에 대해서 짧게 알아보자! useMemo 란? React는 DOM에 변화가 있을 때마다 렌더링을 하는데, 현재 컴포넌트가 리렌더링 되더라도 값의 변화가 없는 경우에 똑같이 리렌더링을 한다면 쓸대없이 자원을 낭비하게 된다. 그래서 변화가 생겼을 때, 현재 함수에 유의미한 변화를 발생시키는 경우에만 연산을 다시 수행하게 해주는 것이 useMemo이다. 즉, 컴포넌트 내부에서 발생하는 연산을 최적화시켜주는 Hook이다. const result = useMemo(countingCallback, [deps]); deps 배열에 들어있는 상태가 변경될 때만 연산을 다..
[JavaScript] Event의 target과 currentTarget
·
JavaScript
Event 객체에는 Target과 currentTarget이 존재한다. const handleClick = (e) => { console.log(e.target); console.log(e.currentTarget); }; 버튼 target은 이벤트를 발생시킨 주체를 의미하고, currentTarget은 이벤트 핸들러를 가지고 있는 요소를 나타낸다. 필요에 따라 target 또는 currentTarget을 사용해서 이벤트 핸들링을 하면 된다.