[react] 성능 개선3

들블리셔·2022년 9월 22일
0

리액트 18버전에서 추가 된 성능 개선 기능 3가지 batching, useTransition, startTransition에 대해서 알아보자.

세 가지의 기능은 모두 재렌더링이 느린 컴포넌트에 대해 성능을 향상 시키는것으로 동일하다.



batching

automatic batching은 재렌더링 방지 기능이다.

setState함수를 연달아 사용하게되면 setState함수 수 만큼 재렌더링이 된다.

하지만 batching기능으로서 리액트가 알아서 마지막 setState함수의 1회만 재렌더링 한다.

setState1()
setState2()
setState3()  // 얘만 1회 재렌더링 됨.



useTransition

재렌더링이 느린 컴포넌트를 우선 만들고 성능 개선을 해보자

import { useState, useTransition  } from 'react'

function Test() {
    let a = new Array(10000).fill(0)
    let [name, setName] = useState('')
    let [isPending, startTransition] = useTransition()
    
    return(
        <div className="App">
            <input onChange={ (e) => {
            	// stratTransition 사용x
                setName(e.target.value)
                
                // stratTransition 사용o
                startTransition( () => {
                    setName(e.target.value)
                }) 
            }} />
            
            {isPending && <h1>please wait.</h1>}
            
            {a.map( () => {
                return (
                    <div>{state}</div>
                )
            })}
        </div>
    )
}

0이 1만개 들어가있는 배열을 생성해서 map으로 input입력 값을 받아서 html을 생성 하게되면 1만개의 div를 렌더링하므로 input에 타이핑하면 지연시간이 생겨 타이핑한 결과가 현저히 느려진다.

하지만 input 입력 값을 받아오는 state인 setName함수를 startTransition으로 감싸준다면 setName함수의 코드는 다른 코드들 보다 나중에 처리하게 된다.

그렇기 때문에 input에 타이핑되는 것을 우선적으로 처리하기때문에 큰 버벅임 없이 즉각처리가 되는 것을 확인할 수 있다.

정리

let [isPending, useTransition] = useTransition;

startTransition은 늦게 처리하고싶을 setState함수에 감싸주면 된다.
isPending은 startTransition이 처리중일 때 true로 변한다.

{isPending && <스피너 컴포넌트/>}
이런식으로 isPending을 응용해서 startTransition이 처리중일때 아주 약간의 지연시간 동안 보여줄 컴포넌트나 html을 보여 줄 수 있다.



useDeferredValue

startTransition과 사용 용도는 동일하다.
하지만 useDeferredValue은 state 아니면 변수하나를 집어넣을 수 있게 되어있다.
집어넣은 변수에 변동사항이 생기면 그걸 늦게 처리해준다.

import { useState, useDeferredValue } from 'react'


function Test() {
    let a = new Array(10000).fill(0)
    let [name, setName] = useState('')
    let [isPending, startTransition] = useTransition()
    let state = useDeferredValue(name);
    return(
        <div className="App">
            <input onChange={ (e) => {
                setName(e.target.value)
            }} />
            {a.map( () => {
                return (
                    <div>{state}</div>
                )
            })}
        </div>
    )
}

useDeferredValue 안에 name을 집어넣으면 그 state가 변동사항이 생겼을 때 let state에 저장해주고 나중에 처리해준다.






이렇게 리액트의 성능 개선 시리즈에 대한 마지막 포스팅을 끝내게 됐는데
모두 비슷한 기능들 같으면서도 살짝씩 다른 이유로 복잡한 부분이 있는 것 같다.

profile
나의 공부방

0개의 댓글