React 성능개선

코쓱타드·2023년 6월 11일
0
post-thumbnail
  1. memo

    자식 컴포넌트의 재랜더링 막기

    <왜 막을까?>

    렌더링 시간이 정말 오래걸리는 자식 컴포넌트라면 부모컴포넌트가 재렌더링 될때 지연시간이 발생하게 된다.

    그래서 컴포넌트를 memo라는 함수에 담아서 꼭 필요할때 재렌더링하게 해서 지연시간을 단축시키는 것이다.

    import  {memo} from 'react';
    
    let Child = memo(function(){
    	return <div>자식컴포넌트</div>
    });

    ⚠️ 왜 memo를 자주 쓰면 좋지 않을까? ⚠️

    memo로 감싸놓은 컴포넌트는 항상 재렌더링 되기 전에 기존 props와 신규 props를 비교하는 비교작업을 한다.

    만약 props가 길고 복잡하다면 오히려 성능면에서 손해일 수 있다.

    꼭 필요한 무거운 컴포넌트에만 사용하는게 좋다.

  2. useMemo

    컴포넌트 로드시 1회만 실행하고 싶은 코드가 있다면 useMemo에 담으면 된다. (useEffect와 비슷한 용도)

    useEffect 처럼 dependency도 넣을 수 있어서 특정 state, props가 변할 때만 실행할 수도 있다.

    <어떨 때 쓰나요?>

    반복문을 1000번 돌려야한다고 가정했을 때, 그 함수를 useMemo에 넣어두면 컴포넌트 로드시 1회만 실행되니 효율적으로 동작한다.

    import {useMemo, useState} from 'react'
    
    function 함수(){
      return 반복문1000번돌린결과
    }
    
    function Cart(){ 
    
      let result = useMemo(()=>{ return 함수() }, [])
    	// []가 dependency이다. 
      return (
        <Child />
        <button onClick={()=>{ setCount(count+1) }}> + </button>
      )
    }
  3. batching

    setCount(1) 
    setName(2) 
    setValue(3)

    state변경함수를 연달아서 3개 사용하면 재렌더링도 3번 되어야하지만 batching 기능이 생기면서 재렌더링을 마지막에 1회만 처리해준다.

    쓸데없는 재렌더링 방지기능이다.

  4. useTransition

    동작이 느린 컴포넌트의 성능을 향상시켜준다.

    import {useState} from 'react'
    // 데이터가 10000개 들어있는 array 자료 
    let a = new Array(10000).fill(0)
    
    function App(){
      let [name, setName] = useState('')
      
      return (
        <div>
          <input onChange={ (e)=>{ setName(e.target.value) }}/>
          {
    				// map 반복문을 사용해서 유저가 input에 입력할 때마다 10000개의 div를 생성하게 함.
            a.map(()=>{
              return <div>{name}</div>
            })
          }
        </div>
      )
    }

    이렇게 되면 유저가 input에 무언가를 입력할 때마다 그 입력한 값을 10000개의 div에 넣어주기 때문에 타이핑한 결과가 바로바로 반응이 오지 않는다.

    import {useState, useTransition} from 'react'
    
    let a = new Array(10000).fill(0)
    
    function App(){
      let [name, setName] = useState('')
    // useTransition()은 아래처럼 사용하면 됩니다~
      let [isPending, startTransition] = useTransition()
      
      return (
        <div>
          <input onChange={ (e)=>{ 
    				// useTransition 변경함수로 state변경함수를 묶었다.
    				// 이렇게하면 다른 코드들보다 나중에 처리해준다.  
            startTransition(()=>{
              setName(e.target.value) 
            })
          }}/>
    
          {
            a.map(()=>{
              return <div>{name}</div>
            })
          }
        </div>
      )
    }

    <동작 원리>

    왜 늦게 동작을 했었냐면 브라우저는 한번에 하나의 작업만 할 수 있는 single-threaded이기 때문이다.

    그런데 startTransition으로 감싸주면 그 안에 있는 코드들을 약간 늦게 처리해준다. (실행시점을 약간 뒤로 늦춤)

    html이 많다면 여러페이지로 나누자!!!

    <isPending는 뭐할때 써요?>

    useTransition 변경함수로 감싼 코드들이 처리중일 때 true가 되는 변수다.

    {isPending ? '로딩중' : <div>로딩완료</div>}

    이런식으로 기능개발을 할 수있다.

  5. useDefeerredValue( )

    state아니면 변수 하나를 집어넣을 수 있다. 그래서 그 state나 변수엥 변동사항이 생기면 그걸 늦게 처리해준다.

import{useState, useTransition, useDeferredValue}from 'react'
let a = new Array(10000).fill(0)

function App(){
	let [name, setName] = useState('')
    let state1 = useDeferredValue(name)
    
    return (
    	<div>
        	<input onChange ={ (e)=>{
          	setName(e.target.value)
          }}/>
        
         {
         	a.map(()=>{
            	return <div>{state1}</div>
            }
         }
        </div>
    )
}

출처. 코딩애플

profile
개발자의 길 from 2022.12

0개의 댓글

관련 채용 정보