본 포스팅은 코딩애플님의 리팩트 강의를 수강한 후 참고하여 작성하였습니다.
SPA 특성상 처음 페이지가 로드될 때 시간이 길게 소요된다.
// import DetailPage from './pages/DetailPage.js'
const DetailPage = lazy(() => import('./pages/DetailPage.js'))
해당 컴포넌트를 브라우저에서 사용할 때 import 할 수 있다.
그러나 이 경우에는 로딩이 오래 걸리는 화면에서는 SSR방식처럼 화면이 깜빡이는 듯한 느낌이 들수도 있다.
<Suspense>
라는 태그를 사용하면 페이지 로딩시간동안 보여주는 페이지를 만들 수 있다.
<Route path='/detail/:id' element={
<Suspense fallback={<div>로딩중입니다!</div>}>
<DetailPage dogs={dogs} />
</Suspense>
} />
state가 변경이 이루어지면 해당 컴포넌트가 재랜더링 될 때
자식컴포넌트도 함께 랜더링 된다.
const Child = memo (() => {
return (
<div>자식컴포넌트</div>
)
})
자식 컴포넌트 선언부분을 memo로 감싸주는것 만으로 부모 컴포넌트의 변경시
자식 컴포넌트가 함께 랜더링 되지 않게 된다.
props가 변경될 때 재랜더링을 실행
어 그러면 무조건 memo 쓰면 좋은거 아니에요 ??
> 무조건 재 랜더링이 아니라, 기존 props와 신규 props를 비교하는 과정이 추가되어 있어서
porps가 길고 복잡하면 오히려 성능저하의 여지가 있다.
const 함수 = () => {
let a = 0;
// 대충 시간이 엄청걸리는 코드
return a;
}
//생략
const Cart = () => {
let a = 함수();
let state = useSelector((state) => {
return state
})
//생략
위와같은 코드가 있을때 state 변경이 있을때마다
해당 함수를 실행하면 성능적으로 매우 나쁜 영향을 미친다.
이를 해결하기 useEffect처럼 컴포넌트 처음 호출시점에만 해당 함수를 실행시키는 기능이다.
let a = useMemo(함수());
이런식으로 함수를 useMemo로만 감싸면 된다!
useEffect와 사용법이 거의 동일하며 dependency를 추가해줄 수도 있다.
let a = useMemo( () => {
함수()
},[]);
실행시점의 차이!
- useEffect
html요소가 전부 랜더링 되면 이후에 해당 코드를 실행- useMemo
html요소와 함께 위에서부터 아래로 읽히는 순서대로 실행
느린 컴포넌트 성능향상기능 (카드빛 돌려막기)
state 변경시 화면이 재랜더링 될 때
시간이 걸리는 요소를 늦게 실행시켜주는 기능
<input onChange={(e) =>{ setName(e.target.value) } }></input>
이렇게 생긴 코드를
let [isPending, startTranstion] = useTransition();
//생략
<div>
<input onChange={(e) => {
startTranstion(() => {
isPending ? '로딩중' :
setName(e.target.value)
})
}}></input>
</div>
이렇게 바꿔주면 브라우저는 다른 중요한 작업을 먼저 수행한 후
startTranstion 안의 코드를 실행시켜주어서
시간이 오래걸리는 요소의 랜더링시 버벅임이 줄어든다.