성능 최적화 하기.

CCY·2020년 6월 13일
0

React 

목록 보기
13/17
post-thumbnail

Todo 2500개 만들어보기..

import React, { useState, useRef, useCallback } from 'react';
import TodoTemplate from './components/TodoTemplate';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';

//성능  최적화 편?

function createBulkTodos() {
  const array = [];
  for (let i = 1; i <= 2500; i++) {
    array.push({
      id: 1,
      text: `할 일 ${i}`,
      checked: false,
    });
  }
  return array;
}

const AppCopy = () => {
  const [todos, setTodos] = useState(createBulkTodos);
  //고유 값으로 사용될 아이디.
  // ref를 사용하여 변수 담기

  const nextId = useRef(2501);
  const onInsert = useCallback(
    (text) => {
      const todo = {
        id: nextId.current,
        text,
        checked: false,
      };
      setTodos(todos.concat(todo));
      nextId.current += 1; //nextId 1씩 더하기
    },
    [todos],
  );
  const onRemove = useCallback(
    (id) => {
      setTodos(todos.filter((todo) => todo.id !== id));
    },
    [todos],
  );

  const onToggle = useCallback(
    (id) => {
      setTodos(
        todos.map((todo) =>
          todo.id === id ? { ...todo, checked: !todo.checked } : todo,
        ),
      );
    },
    [todos],
  );

  return (
    <TodoTemplate>
      <TodoInsert onInsert={onInsert} />
      <TodoList todos={todos} onRemove={onRemove} onToggle={onToggle} />
    </TodoTemplate>
  );
};

export default AppCopy;

1.Inspector (performance)

chrome developer tools 로 성능 확인하기 => inspector => performace => record (녹화버튼) 클릭.. => 원하는 Action 완료후 멈춤.

2. Inside Preformance 확인하기

Timing 이라는 곳에 들어가서 나의 파일을 확인하면 2.05초 가 걸렸다고 나옴....(사람들 컴퓨터마다 다르다고 한다...) ...근대 2초가 길은것인가? 솔직히 차이 느껴졌음...만약에 안좋은 컴퓨터 쓰는 사람이면...정말 답답할것 같음...

느려지는 원인 분석..

컴포넌트가 리렌더 되는 상황들

  • 자신이 전달받은 props 가 변경될 때
  • 자신의 state가 바뀔때
  • 부모 컴포넌트가 리렌더링될 때
  • forceUpdate 함수가 실행될 때.

할일 1을 체크 할 경우 App 의 state 가 변경됨.
할일 1번만 update되면 되지만 2부터 2500까지 모두 update되면서 리렌덩이 느려지는것임.

해결 방법:

방법1

shouldComponentUpdate 이 함수형에없으니 대신 React.memo() 사용

const TodoListItem = ({ todo, onRemove, onToggle }) => {
  const { id, text, checked } = todo;
  return (
    <div className="TodoListItem">
      <div className={cn('checkbox', { checked })} onClick={() => onToggle(id)}>
        {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
        <div className="text">{text}</div>
      </div>
      <div className="remove" onClick={() => onRemove(id)}>
        <MdRemoveCircleOutline />
      </div>
    </div>
  );
};

export default React.memo(TodoListItem);

props 가 바뀌지 않는 이상 리렌더링 하지 않도록 설정하는 함수형 컴포넌트.

그런데 onRemove 와 onToggle 을 사용하면 프로젝트의 배열이 바뀌기(update) 때문에 바꿔줘야함..

useState 업데이트 함수를 추가하라

useState

  • 업데이트를 어떻게 할지 정의 주는 업데이트 함수를 추가 하면 됨.
예시 코드:
const[number,setNumber]=useState(0)

const onIncrease=useCallback(
  ()=>setNumber(prevNumber => prevNumber +1),[])
//prevNumber 는 현재 number 값을 가리킴
// 현재 숫자 값에서 +1을 업데이트 하라? : (업데이트를 어떻게 할것인지 정의해 주는 업데이트 함수)

실제 코드

  const onRemove = useCallback((id) => {
    setTodos((todos) => todos.filter((todo) => todo.id !== id));
  }, []);

  const onToggle = useCallback((id) => {
    setTodos((todos) =>
      todos.map((todo) =>
        todo.id === id ? { ...todo, checked: !todo.checked } : todo,
      ),
    );
  }, []);

결과

profile
✍️ 기록을 습관화 하자 ✍️ 나는 할 수 있다, 나는 개발자가 될거다 💪🙌😎

0개의 댓글