[React] React 성능개선 danymic import : lazy import

BAEJUN SON·2023년 11월 8일

React

목록 보기
9/10
post-thumbnail

React의 초기로딩

React는 SPA이다. webpack같은 번들러로 코드를 번들하고, html 파일에서 번들된 자바스크립트 파일을 불러와서 웹앱을 브라우저에서 실행한다.

그런데 번들 파일이 다 불러와져야 실행되다 보니, 웹앱의 크기가 커지면 커질수록 성능에 악영향을 끼치게 된다.
쉽게 말해 자바스크립트 파일의 크기가 커질수록 초기 로딩 속도가 오래걸린단 소리다(초기에 모든 JS파일을 번들하니)

그럼 어떡함?

원인은 JS파일을 초기에 다 가져오기에 발생하는 속도저하 아닌가.
그럼 분할해서 갖고와보자
이를 코드 분할(code splitting)이라 한다

번들 파일의 코드를 분할하여, 모든 코드를 한번에 불러오지 않고 사용자가 필요로 할 때에 필요한 코드만 불러오는 개념이다.

React.lazy

왜 사용하는가 ?

React에서 컴포넌트 파일을 정의하고 동적 불러오기를 사용하면 에러가 발생한다. 컴포넌트를 동적으로 불러오기위해서 필요한것이 React.lazy다

import { lazy, Suspense } from "react";

const DetailPage = lazy(() => import("./routes/Detail.js"));
const Cart = lazy(() => import("./routes/Cart.js"));

<Suspense fallback={<div>로딩중임!</div>}>
	<Routes>
		<Route>
			<DetailPage />
		</Route>
	</Routes>
</Suspense>

React.lazy()는 import() 구문을 반환하는 콜백함수를 인자로 받는다. 이때

  1. 동적 불러오기로 불러와지는 모듈은 ReactComponent를 포함하여
  2. default export를 가진 모듈이어야 한다.
    그리고 import 해온 컴포넌트를 반환한다.

React.lazy로 불러온 컴포넌트는 단독으로 쓰일 수 없고, React.Suspense 컴포넌트의 하위에서 렌더링 되어야한다.

Suspense는 fallback prop을 필수로 하는데
fallback prop에선 로딩 표시기로 사용할 컴포넌트를 실행한다.

권장 사용법

이를 시작하기 좋은 장소는 라우트입니다. 웹 페이지를 불러오는 시간은 페이지 전환에 어느 정도 발생하며 대부분 페이지를 한번에 렌더링하기 때문에 사용자가 페이지를 렌더링하는 동안 다른 요소와 상호작용하지 않습니다.

그렇다면 React.lazy를 어디에 적용하는 것이 좋을까?

React 공식문서의 코드 분할 항목에 의하면, Router 바로 아래에 Suspense를 위치시키고, Route로 보여줄 컴포넌트들을 React.lazy로 불러올 것을 권장하고 있다.
아래가 그 예시 코드이다.

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
);

쉽게 말하면 한번에 다 가져오면 초기로딩이 너무 오래걸리니, 각 컴포넌트들을 분할해서 필요할때 가져오자는거다. 그렇게되면 초기로딩은 빨라지겠지만 각 컴포넌트로 이동할때마다 어느정도 소요시간이 필요하고?(기존의 SPA는 다 가져와서 슉슉 보여주기때문에 이게 없었는데), 그 소요시간동안 로딩페이지를 Suspense의 fallback prop을 통해 전달하면 된다.

성능개선을 위한 움직임을 밟을 줄 알아야 한다. 단순 동작만 하는 코드는 아무짝에 쓸모가 없..지는 않겠지만, 높은 사용성을 제공하지 못한다면 SPA의 존재이유는 무엇이란 말이가~

참고문헌

0개의 댓글