[React] 느린 컴포넌트 성능 향상 useTransition, useDeferredValue
[React] 느린 컴포넌트 성능 향상 useTransition, useDeferredValue
react 18 버전에서 새롭게 추가된 hook이 있다.
useTransition
useTransition을 사용하면 동작이 느린 컴포넌트들을 혁신적으로 빠르게 동작시킬 수가 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// App.js
import { useState } from "react";
function App(){
let [name, setName] = useState('');
let arr = new Array(10000).fill(0); // 0이 10000개 담긴 arr
return (
<div className="App">
<input onChange={(e)=>{ setName(e.target.value) }} />
{
arr.map(()=>{
return <div>{name}</div>
})
}
</div>
)
}
input에 유저가 글을 입력하게 되면 그 값을 name 이라는 state에 저장한 후 arr의 갯수(10000개)만큼 뿌려주는 코드다.
유저가 타이핑을 입력할때마다 10000개의 div박스를 생성하기 때문에 매우 느리다.
성능저하의 원인이 되는 부분을 startTransition으로 감싼다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// App.js
import { useState, useTransition } from "react";
let arr = new Array(10000).fill(0); // 0이 10000개 담긴 arr
function App(){
let [name, setName] = useState('');
let [isPending, startTransition] = useTransition()
return (
<div className="App">
<input onChange={(e)=>{
startTransition(()=>{
setName(e.target.value)
})
}} />
{
isPending
? '로딩중...'
: arr.map(()=>{
return <div>{name}</div>
})
}
</div>
)
}
브라우저는 한번에 한가지 작업밖에 못하는데,
위의 같은 경우에는 input에 글자를 보여주기, div * 10000 만들기 2가지 일을 해야 하기때문에 버벅거리게 된다.
그런데 startTransition 함수로 감싸게 되면 startTransition안의 코드를 늦게 실행한다.
startTransition으로 실행 시점을 조절함으로써 성능 향상의 효과를 기대할 수 있다.
startTransition === 늦게처리
isPending은 startTransition이 처리중일 때 true를 반환한다.
useDeferredValue
useDeferredValue를 사용해도 느린 컴포넌트의 성능을 향상시킬 수있다.
useDeferredValue() 함수 안에 넣은 state는 늦게 처리해준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// App.js
import { useState, useTransition, useDeferredValue } from "react";
let arr = new Array(10000).fill(0); // 0이 10000개 담긴 arr
function App(){
let [name, setName] = useState('');
let [isPending, startTransition] = useTransition()
let state = useDeferredValue(name)
return (
<div className="App">
<input onChange={(e)=>{
startTransition(()=>{
setName(e.target.value)
})
}} />
{
isPending
? '로딩중...'
: arr.map(()=>{
return <div>{state}</div>
})
}
</div>
)
}
This post is licensed under CC BY 4.0 by the author.