개발자도구 (React Developer Tools)

코드를 짜다보면, 의도와 다르게 동작하는 경우 ex) props가 제대로 출력이 안된다. 이미지가 제대로 안뜬다.

왜 안되는지 볼려면 일단 기본적으로 개발자도구를 열어서 확인한다.

크롬 웹스토어 : React Developer Tools

Component 탭을 보면

그러면 컴포넌트 insepct 가능하고 props도 다 볼수 있다.

해당 컴포넌트의 소스파일로도 갈 수 있다.

Profiler 라는 애도 슬 수 있는데

컴포넌트마다, 몇초 걸렸는지도 알 수 있음.

느린 컴포넌트에 대해서 범인 찾는 탭이다.

녹화 버튼 누르면 액션들을 보여준다.

어떤 컴포넌트들이 렌더링 되고 있는지를 알려준다.

  • 서버가 느린건 예외
  • Redux Dev tools 도 있음 (상태관리 tracking 가능함)

js 자르기

Single Page Application 발행하면 하나의 html, js 파일로 된다.

하나의 js 안에 모든 코드들이 들어가 있음. 사이즈가 클 수 밖에 없음. 로딩 속도가 느릴 수 밖에 없음.

이 js 파일을 잘게 분할하고 싶다면?

import {lazy, Suspense} from 'react';
const Detail = lazy(()=> import('./routes/Detail.js'));

<Suspense fallback = {<div> 로딩중임 </div>}>
  <Detail></Detail>
</Suspense>

위와 같이 사용하면 lazy 하게 가져옴.

먼저 가져와야 하는것만 가져올 수 있으니 첫 화면은 빠르게 가져올 때 사용한다.

재렌더링 막는 memo, useMemo

memo

자식컴포넌트 재렌더링 막기

function Child() {
  return <div> 자식임 </div>
}

...
function Cart() {
  ...
  <Child></Child>
  ...
}

위와 같이 사용하면 Cart가 렌더링 될 때 Child도 재렌더링 된다. 만약 Child가 무거운 컴포넌트라면 성능에 문제를 줄 수 있다.

꼭 필요할 때만 재렌더링하려면 memo를 사용한다.

let Child = memo (function() {
  return <div> 자식임 </div>
})

...
function Cart() {
  ...
  <Child></Child>
  ...
}

위와 같이 memo 로 감싸주면

꼭 필요할 때만 제랜더링해줌.

memo 는 특정상황일 때만 렌더링되게 해주는 애임 특정상황?

Child가 변화될 때. 전달되는 props 값이 변화될 때

맨날 갔다 쓰면 안됨. 결국 props간에 비교작업을 계속할 것이기 때문임.

꼭 필요한 무거운 컴포넌트에만 넣어보자.

useMemo

function 함수() {
  return 반복문 10억번
}

...
function Cart() {
  let result = 함수();

}

이렇게라고 하면 렌더링 될 때마다 함수를 실행하니 비효율적임

이를…

function 함수() {
  return 반복문 10억번
}

...
function Cart() {
  let result = useMemo(() => {return 함수()}, [state]);
}

state가 변화될 때만 실행해줌.

useEffect랑 거의 동일함.

차이점은 useEffect : 렌더링 다 되고 실행 useMemo : 렌더링 될 때 실행

useTransition, useDeferreedValue

리액트 신규 기능

 1. batch 기능
 2. useTransition으로 느린컴포넌트 성능 향상 가능 
  카드 빚 돌려막기

state 1번 변경 state 2번 변경 state 3번 변경

마지막에만 딱 렌더링 일어남 (3번에서만)

리액트 18 ajax, setTimeout

<input onChange={(e) => {setName(e.target.value) }} />;
<div>{name}</div> * 10000 

위와 같이한다면, div 1000개로 인해서 성능저하가 일어남. 굉장히 느리게 동작하는 것을 볼 수 있다.

해결책 솔루션 1. html 10000 개 지우기 솔루션 2. usetransition

import {useState, useTransition} from 'react';
...

  let [isPending, startTransition] = useTransition();

...

<div>
  <input
    onChange={e => {
      startTransition(() => {
        setName(e.target.value);
      })
    }}
  />
  ;{
    a.map(() => {
      return <div>{name}</div>
    })
  }
</div>

위와 같이 문제를 일으키는 state 변경함수를 startTransition으로 감싸준다.

startTransition의 원리
코드 시작 시점을 뒤로 늦춰준다.다른 작업을 먼저하고
1. a를 input에 보여주기
2. 그 후 div 에 넣어준다.

늦게처리를 도와주는 것이기 때문에 한꺼번에 작업해준다.

  • isPending은 언제쓰냐 startTransition이 처리중일 때 true가 되는 함수임

이걸 써서 로딩중이라고 말할 수 있다.

useDefferedValue

이걸 써도 느린 컴포넌틑 성능 향상 가능

let state = useDefferedValue(name)

name 이란 애가 변경할 때마다 늦게 처리를 해준다.