Post

[React] lazy import 코드분할과 Suspense

[React] lazy import 코드분할과 Suspense

리액트에서 빌드를 하게되면 html, js 파일이 1개만 생성된다.
그 안에 지금까지 만든 컴포넌트 내용들이 들어있어 파일 사이즈가 크다.
그래서 리액트 사이트들은 첫 페이지 로딩속도가 매우 느릴 수 있는데,
이 현상을 해결하려면 JS파일을 잘게 쪼개면 된다.

쪼개는 방법은 import 문법을 약간 수정하면 된다

1
2
3
// App.js
import Detail from './routes/Detail.js'
import Cart from './routes/Cart.js'

위 코드를 으래 코드로 수정하면 된다.

1
2
3
4
5
// App.js
import {lazy, Suspense, useEffect, useState} from 'react'

const Detail = lazy( () => import('./routes/Detail.js') )
const Cart = lazy( () => import('./routes/Cart.js') )

lazy 문법으로도 똑같이 import가 가능한데,
위 경우엔 “Detail 컴포넌트가 필요해지면 import 해주세요” 라는 뜻이 된다.

이렇게 import 하게 되면 빌드 시 Detail 컴포넌트를 다른 파일로 쪼개준다.

Suspense

lazy 문법을 사용하면 당연히 Detail 컴포넌트 로드까지 지연시간이 발생할 수 있게 된다. 그럴 땐

  1. Suspense 를 import 한다.
  2. Detail 컴포넌트를 감싸준다.

Detail 컴포넌트가 로딩중일 때 대신 보여줄 html 작성을 할 수 있다.
귀찮으면 <Suspense> 이걸로 <Routes> 전부 감싸도 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// App.js

<Suspense fallback={<div>Loading...</div>}>
  <Routes>
    <Route path="/" element={<Index prd={prd} setPrd={setPrd} req={req} setReq={setReq} />} />
    <Route path="/detail/:prdId" element={<Detail prd={prd} />}/>

    <Route path="/about" element={<About />}>
      <Route path="shopping" element={<AboutShopping />} />
      <Route path="delivering" element={<AboutDelivering />} />
    </Route>

    <Route path="/cart" element={<Cart />} />

    <Route path="*" element={<div style={{padding:"2rem"}}>There's nothing here!</div>} />
  </Routes>
</Suspense>
This post is licensed under CC BY 4.0 by the author.