성능 최적화

js·2022년 7월 12일
0

리액트로 성능문제를 겪고 있고, 리액트의 경고 메시지들이 본인의 앱을 느리게 만들고 있다면 Brunch, Browserify, Rollup등과 같은 production build 라이브러리를 사용해야 합니다.

하지만, 대부분이 webpack 개발환경 아래에 놓여있기 때문에 Webpack v4이상에서 아래와 같이 terser plugin을 사용하는게 좋습니다.

webpack

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimizer: [new TerserPlugin({ /* additional options here */ })],
  },
};

<주의사항>

  • production 빌드에서만 필요한 작업이다

  • React의 유용한 경고를 숨기고 빌드를 훨씬 느리게 만들기 때문에 TerserPlugin을 개발 중에 적용하지 말자

DevTools Profiler로 컴포넌트 프로파일링

react-dom 16.5+와 react-native 0.57+는 React DevTools Profiler를 사용하여 개발 모드에서 향상된 프로파일링 기능을 제공한다.

자세한 프로파일러 사용법은 여기서 확인이 가능하다.

리스트 컴포넌트 가상화

데이터를 많이 불러와야할 리스트 컴포넌트의 경우 windowing 이라는 기법을 추천합니다. windowing은 리스트 컴포넌트의 일부분만 렌더링하여 리렌더링 하는 시간과 비용을 줄일 수 있습니다.

react-windowreact-virtualized가 대표적인 windowing 라이브러리입니다.

재조정을 피하기

컴포넌트의 prop 혹은 State가 변경되면 새로 반환된 요소와 이전에 렌더링된 요소를 비교해서 실제 DOM을 업데이트 할지 결정하는데, 같지 않을 경우 업데이트를 합니다

리액트가 변경된 DOM 노드만 업데이트하더라도 리렌더링에는 시간이 어느정도 걸리는데, 이 리렌더링 시간이 눈에 띄게 오래 걸릴 경우 shouldComponentUpdate 함수로 업데이트를 막을 수 있고 이를통해 최적화를 이룩할 수 있습니다.

// 해당 함수의 기본은 True를 반환하고 React는 DOM을 업데이트합니다
shouldComponentUpdate(nextProps, nextState) {
  return true;
}

업데이트를 할 필요가 없으면 shouldComponentUpdate에서 False를 반환하여 일련의 불필요한 리렌더링 과정을 방지 할 수 있습니다.

대부분의 경우 shouldComponentUpdate()를 직접 작성하는 대신 React.PureComponent에서 상속해서 사용할 수 있습니다. 그것은 현재와 이전의 prop과 state의 얕은 비교로 shouldComponentUpdate()를 호출하는 것과 같습니다.
이때 주의할점으론 얕은 비교만 수행하므로, state나 props가 변화하면 아무런 의미가 없습니다.

데이터를 변형시키지 않음으로써 얻는 효과

요약: 기존 사용중인 propsstate를 변경하지 말자

배열을 변경시

새로운 배열을 반환하는 concat() 또는 spread operator 사용

handleClick() {
  this.setState(state => ({
    words: state.words.concat(['marklar'])
  }));
}
handleClick() {
  this.setState(state => ({
    words: [...state.words, 'marklar'],
  }));
};

객체를 변경시

새로운 객체를 반환하는 Object.assign() 또는 spread operator 사용

원본 변경 ❌

function updateColorMap(colormap) {
  colormap.right = 'blue';
}

얕은 복사 ✅

function updateColorMap(colormap) {
  return Object.assign({}, colormap, {right: 'blue'});
}
function updateColorMap(colormap) {
  return {...colormap, right: 'blue'};
}

깊은 복사를 원하면?

가독성 있는 코드를 위해 라이브러리를 사용합시다

immer 또는 immutability-helper

0개의 댓글