| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 28 | 29 | 30 | 31 |
- JWT
- Front-End
- VUE
- spring
- 정보처리기사
- 웹개발자
- spring boot
- It
- TS
- 백엔드
- 정보처리기사 실기
- TypeScript
- 스프링부트
- 수제비
- frontend
- Node.js
- useState
- JS
- security
- spring boot security
- 자바스크립트
- 백엔드개발자
- Authentication
- JavaScript
- 프론트엔드
- React
- 큐넷
- 타입스크립트
- Redux
- 리액트
- Today
- Total
솔적솔적
React- 성능개선3. useTransition, useDeferredValue 본문
React- 성능개선3. useTransition, useDeferredValue
카드값줘체리 2022. 9. 11. 19:23리액트가 업데이트되고 나서 사용할 수 있는 신기능이 있다는데, 그것을 오늘 사용해보려한다.
| 1. batch 기능
state변경함수들이 쭉 작성이 되어있다면 state변경이 일어날 때마다 재랜더링이 일어나는데
연달아서 여러개가있다면 재랜더링이 맨 마지막것만 재렌더링 1번만 일어나게하는 것이다. 이게 batch이라고 하는데,
예외가 있다. ajax요청, setTimeout 등의 내부코드라면 batch이 일어나지않았는데,
리액트 17버전에는 배칭이 일어나지않는다.
리액트 18버전이후에는 코드가 어디있던간에 잘 일어난다는 것.
| 2. useTransition
동작이 느린 컴포넌트들을 빠르게 동작할 수 있게하는 것이다.
import {useState} from "react";
function App2(){
const [name, setName] = useState('');
return (
<>
<input onChange={(e) =>{setName(e.target.value)}} />
</>
)
}
유저가 input에 뭔가 입력을 하면 name란 state에 저장하도록 하였다.
근데 갑자기 성능저하가 일어났다고 가정을 해보자.
div박스를 천개, 만개정도 만들게되었다치자.
div를 여러개 만드려면 반복문을 사용하겠지.
map을 통해서 div박스들을 반복생성하도록하겠지.
import {useState} from "react";
const divBox = new Array(10000).fill(0);
function App2(){
const [name, setName] = useState('');
return (
<>
<input onChange={(e) =>{setName(e.target.value)}} />
{
a.map(()=>{
return <div>{name}</div>
})
}
</>
)
}
이렇게 코드를 짜고 직접 input란에 입력하여 실행해보면 반응이 느려지는 것을 알 수 있다.
타이핑을 할 때마다 name란 state가 변경이되고 만개정도 생성을 재랜더링해야하기 때문에 느려지는 것이다.
이런 식으로 코드를 짜면 느려지고 문제가 생긴다. 반응이 느린 것을 유저한테 느껴지게한다면 부정적인 효과가 생긴다는 것.
여기서 해결책은 무엇이겠는가?
해결방법 1 : 10000개를 지워야지모...
해결방법 2 : 꼭 만개를 굳이 보여줘야한다면 리액트 18버전 이후 부터 쓸 수 있는 이 useTransition을 import한다음에 사용하도록하는 것이다.
import {useState, useTransition} from "react";
const divBox = new Array(10000).fill(0);
function App2(){
const [name, setName] = useState('');
const [isPending, startTransition] = useTransition();
return (
<>
<input onChange={(e) =>{
startTransition(()=>{
setName(e.target.value)
})
}} />
{
a.map(()=>{
return <div>{name}</div>
})
}
</>
)
}
startTransition으로 해당 state변경 감싸기를 완료한 뒤
다시 실행해보면 아까보다는 성능이 나아진 것을, 빨리 동작하는 것을 느낄 수 있을 것이다.
그럼 이 동작원리에 대해서 알아보자.
| startTransition 동작원리
우선, 처음 실행했을 때 왜 늦게 동작을 했었냐면 브라우저는 동시작업을 못하기 때문이다.
한번에 하나의 작업만 수행할 수 있다는 것(single-threaded)
그래서 input란에 타이핑을 했을 때 브라우저가 해야할 작업은
input 에 입력된 것을 보여주고 div박스 만개를 동시에 처리하려고하니 느리게 동작되게 되는 것이다.
그래서 startTransition()로 감싸면 이 함수 안에있는 것을 늦게 처리하게해준다.
시작 시점을 뒤로 늦춰준다는 것.
다른 중요한 작업들을 먼저하게끔하는 것.
그럼 브라우저는 중요한 작업 이후에 state감싼 것을 이후에 실행되도록하여 성능향상을 올리는 것이다.
그럴 때 갖다쓰면 좋음좋음
| 3. useDeferredValue를 써도 느린 컴포넌트 성능 향상 가능
import {useState, useTransition, useDeferredValue} from "react";
const divBox = new Array(10000).fill(0);
function App2(){
const [name, setName] = useState('');
const [isPending, startTransition] = useTransition();
useDeferredValue();
return (
<>
<input onChange={(e) =>{
startTransition(()=>{
setName(e.target.value)
})
}} />
{
isPending ? '로딩중입니다' :
a.map(()=>{
return <div>{name}</div>
})
}
</>
)
}
useDeferredValue(); // 감싸진 않지만 state, props를 넣어서 사용할 수 있다.
이 useDeferredValue()에 넣어둔 state는 늦게 처리가 된다. 변동사항이 생겼을 때 늦게 변화한다는 것.
늦게 처리되길 원하는 state가 있다하면 변수로 빼서 활용하도록한다.
import {useState, useTransition, useDeferredValue} from "react";
const divBox = new Array(10000).fill(0);
function App2(){
const [name, setName] = useState('');
const [isPending, startTransition] = useTransition();
const state = useDeferredValue(name); // 감싸진 않지만 state, props를 넣어서 사용할 수 있다.
return (
<>
<input onChange={(e) =>{
startTransition(()=>{
setName(e.target.value)
})
}} />
{
isPending ? '로딩중입니다' :
a.map(()=>{
return <div>{state}</div>
})
}
</>
)
}
name이라는 state가 변할 때마다 늦게 처리하게끔해줌.
중요한 처리를 먼저, 그다음 나중에 실행되게함.
'Front-end > REACT - 성능개선 lazy, memo, useTransition' 카테고리의 다른 글
| REACT- 성능개선2, memo, useMemo 불필요한 재렌더링은 저리가! (0) | 2022.09.10 |
|---|---|
| REACT- 성능개선1, lazy loading 성능개선을 위해 해야할 것을 알아보자. (0) | 2022.09.10 |