관리 메뉴

사과하는 제라스

리액트에서 성능 향상하기 - 리렌더링 줄이기! 본문

제라스가 React를 다루는 방법

리액트에서 성능 향상하기 - 리렌더링 줄이기!

Xerath(제라스) 2023. 1. 8. 13:50

목차

    728x90
    반응형

    성능을 최적화하는 수단은 여러가지가 존재한다.

     

    1. React.memo를 사용한다.

    React.memo로 어떤 컴포넌트의 export 값을 감싸주면 해당 컴포넌트의 props가 바뀌지 않았다면, 리렌더링을 하지 않도록 설정함.

    -> 함수 컴포넌트의 리렌더링 성능을 최적화해 줌.

     

    주로 리스트 관련 컴포넌트를 작성할  때는 리스트의 아이템, 리스트 이 두개의 컴포넌트를 React.memo를 통해 최적화해주어야 한다.

     

    2. useState의 함수형 업데이트

    useState의 함수들을 함수형으로 사용하면 된다.

    예를 들면 다음과 같다.

    const [data, setData] = useState('');
    
    function test() {
    	setData(data => data = newData); //이런 식으로 setData를 사용 시 (인자 => 인자에 대한 식);으로 쓰면 된다.
    }

     

    3. useReducer를 사용한다.

    조금 복잡하긴하다. 2번 대신으로 사용하는 것으로 주로 Redux를 잘 다룬다면 쉽게 사용할 수 있다. 장점으로는 컴포넌트의 바깥에 업데이트하는 로직들을 모아둘 수 있다.

     

    import { useCallback, useReducer, useRef } from 'react';
    import './App.css';
    import TodoInsert from './components/TodoInsert';
    import TodoList from './components/TodoList';
    import TodoTemplate from './components/TodoTemplate';
    
    function createBulkTodos() {
      const array = [];
      for (let i = 1; i <= 2500; i++) {
        array.push({
          id: i,
          text: `Todo ${i}`,
          checked: false,
        });
      }
      return array;
    }
    
    function todoReducer(todos, action) {
      switch (action.type) {
        case 'INSERT':
          return action.tempTodos;
        case 'REMOVE':
          return todos.filter((todo) => todo.id !== action.id);
        case 'TOGGLE':
          return todos.map((todo) =>
            todo.id === action.id ? { ...todo, checked: !todo.checked } : todo,
          );
        default:
          return todos;
      }
    }
    const App = () => {
      const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos);
    
      const nextId = useRef(2501);
      const onInsert = useCallback(
        (text) => {
          const tempTodos = [...todos, { id: nextId, text, checked: false }];
          dispatch({ type: 'INSERT', tempTodos });
          nextId.current += 1;
        },
        [todos],
      );
    
      const onRemove = useCallback((id) => {
        dispatch({ type: 'REMOVE', id });
      }, []);
    
      const onToggle = useCallback((id) => {
        dispatch({ type: 'TOGGLE', id });
      }, []);
      return (
        <TodoTemplate>
          <TodoInsert onInsert={onInsert} />
          <TodoList todos={todos} onRemove={onRemove} onToggle={onToggle} />
        </TodoTemplate>
      );
    };
    
    export default App;

    -> 이런 식으로 useReducer로 상태 업데이트에 대한 관리를 수행하고 각 업데이트 함수들에 dispatch를 통해 업데이트를 진행하면 된다.

     

    4. react-virtualized를 사용한 렌더링 최적화

    스크롤하기 전에 보이지 않는 영역에 대해선 미리 공간을 잡아두기만 하고 렌더링을하지 않는 방식이다.

    다음과 같이 라이브러리를 설치해서 사용한다.

    yarn add react-virtualized

    [출처] 리액트를 다루는 기술

    728x90
    반응형