리액트 성능 최적화 방법
컴포넌트 리렌더링 최적화
리액트 컴포넌트는 상태나 props가 변경될 때마다 렌더링됩니다. 그러나 불필요한 리렌더링은 성능을 저하시킬 수 있습니다. React.memo는 함수형 컴포넌트의 리렌더링을 최적화하는 데 사용됩니다. 이 함수는 props가 변경되지 않으면 컴포넌트를 다시 렌더링하지 않도록 합니다. 클래스형 컴포넌트에서는 shouldComponentUpdate 메서드를 사용하여 리렌더링 여부를 제어할 수 있습니다. 또한, PureComponent는 props와 state의 변경이 없는 경우 자동으로 리렌더링을 방지합니다.
React.lazy와 Suspense를 이용한 코드 분할
코드 분할은 애플리케이션의 초기 로딩 속도를 개선하는 데 매우 중요합니다. React.lazy와 Suspense를 사용하여 컴포넌트를 동적으로 로드할 수 있습니다. 이를 통해 필요한 컴포넌트만 로드하고, 나머지 코드는 지연 로딩하여 애플리케이션의 초기 로딩 시간을 단축시킬 수 있습니다. React.lazy는 import() 구문을 사용하여 비동기적으로 컴포넌트를 불러오며, Suspense는 컴포넌트가 로드될 때 로딩 상태를 표시할 수 있습니다. 이를 통해 불필요한 리소스를 미리 로드하는 것을 방지할 수 있습니다.
불변성 유지 및 상태 최적화
리액트에서 상태를 업데이트할 때 불변성을 유지하는 것이 성능 최적화에 중요합니다. 상태를 직접 수정하지 않고, 항상 새로운 객체나 배열을 반환해야 변경 사항을 추적하고 리렌더링을 효율적으로 관리할 수 있습니다. 예를 들어, 배열에 요소를 추가할 때는 push 대신 concat을 사용하고, 객체의 속성을 업데이트할 때는 Object.assign이나 스프레드 연산자 (...)를 사용하여 새 객체를 반환해야 합니다. 불변성을 지키는 것이 리액트의 효율적인 상태 관리와 성능 향상에 큰 도움이 됩니다.
렌더링 성능 최적화를 위한 이벤트 핸들러 최적화
이벤트 핸들러는 리액트 컴포넌트에서 자주 호출되는 함수이므로, 이를 최적화하는 것이 중요합니다. 매번 렌더링될 때마다 새롭게 이벤트 핸들러가 생성되면, 불필요한 리렌더링이 발생할 수 있습니다. 이를 방지하기 위해 이벤트 핸들러를 클래스 컴포넌트의 bind를 사용하거나, 함수형 컴포넌트에서는 useCallback 훅을 사용하여 함수의 참조를 메모이제이션할 수 있습니다. useCallback은 함수가 의존하는 값이 변경되지 않는 한, 동일한 함수 참조를 유지하게 도와줍니다.
배치 업데이트 및 비동기 업데이트 활용
리액트는 상태 업데이트가 여러 번 발생하더라도 이를 배치 처리하여 성능을 최적화합니다. 그러나 때때로 배치 업데이트를 명시적으로 관리할 필요가 있을 수 있습니다. ReactDOM.flushSync()를 사용하여 업데이트를 동기적으로 처리하거나, useEffect 훅을 활용해 상태 업데이트를 비동기적으로 처리할 수 있습니다. 또한, setState가 비동기적으로 동작하기 때문에 상태 업데이트 후 즉시 변경된 상태를 참조하려면 콜백 함수를 사용할 수 있습니다. 이러한 최적화 기법을 통해 리렌더링 횟수를 최소화하고 성능을 개선할 수 있습니다.