React.lazy와 @loadbale/component의 차이점

사공 오·2023년 9월 12일
3

리액트로 진행한 프로젝트을 라이트하우스로 돌려봤고 그 중 나온 권장 사항이 사용하지않는 자바스크립트 줄이기였다. 해당 글에서는 위의 이미지와 같이 리액트에서는 code-split을 추천했고 React.lazy()를 사용하기로 했다.

기존 코드

import HomePage from './HomePage/HomePage';
import MainPage from './MainPage/MainPage';
import LoginPage from './LoginPage/LoginPage';
...

export default function AppRouter() {
  return (
        ...

수정된 코드

const HomePage = lazy(() => import('./HomePage/HomePage'));
const MainPage = lazy(() => import('./MainPage/MainPage'));
const LoginPage = lazy(() => import('./LoginPage/LoginPage'));
...

export default function AppRouter() {
  return (
    <Suspense fullback={<Spinner />}>
      ....
      </Suspense>

이렇게 코드를 수정했다. React.lazy()를 사용한다면 <Suspense>도 필수적으로 사용해야한다. 이때 fullback안의 요소가, 비동기 작업이 자식 컴포넌트에서 처리되기 전에 보이게 된다.

이를 사용하여 번들의 크기를 줄이고, 초기 렌더링에서 사용되지 않는 컴포넌트를 불러오는 작업을 지연시킬 수 있다.



위의 라이트하우스에서 권장하는 @loadbale/component는 lazy와 어떤 차이가 있을까?


어떤 차이점이 있는지 궁금해 찾아보니 What are the differences between React.lazy and @loadable/components?라는 글을 발견했고 위와 같은 표를 확인할 수 있었다.

  1. SSR에서는 React.lazy를 사용할 수 없다.

  2. <Suspense/>의 경우 React.lazy()에서는 필수적이었던 반면에 @loadbale/component에서의 경우 선택적으로 사용할 수 있다고 한다.

  3. @loadbale/component에서는 Library Splitting을 render props를 사용해 지원한다고 한다.

import loadable from '@loadable/component'
const Moment = loadable.lib(() => import('moment'))
function FromNow({ date }) {
	return (
		<div>
			<Moment fallback={date.toLocaleDateString()}>
				{({ default: moment }) =>
					moment(date).fromNow()}
			</Moment>
		</div>
	)
}
  1. 웹팩은 full dynamic imports 혹은 aggressive 코드 스플리팅을 지원한다. 따라서 재사용 가능한 Loadable Component를 만들고 dynamic import 함수에 dyname value를 넘겨서 사용할 수 있다.
import loadable from '@loadable/component'
const AsyncPage = loadable(props =>
	import(`./${props.page}`))
function MyComponent() {
return (
	<div>
	<AsyncPage page="Home" />
	<AsyncPage page="Contact" />
	</div>
)
}

이번 프로젝트는 CSR이었기에 lazy()를 사용하였으나 다음에는 SSR에서 @loadbale/component를 사용해보려고한다. 또 3번도 three.js를 쓸 때 번들이 커서 라이트하우스에 자꾸 걸리는게 마음에 걸렸는데 이를 사용하면 해결할 수 있을 것 같아 다음 프로젝트에서 사용해보려고 한다!


그 외 참고글

https://evan6-6.tistory.com/110
https://lakelouise.tistory.com/327

0개의 댓글