lazy-loading with react-router-dom

Ryan Cho·2024년 11월 27일
0

이번엔 react-router-dom에서 제공하는 lazy프로퍼티에 대해 알아보자.

트리쉐이킹을 위해 LazyLoading을 적용하면서 기본 리액트가 제공하는 lazy와 Suspense를 이용한 방법과 router에서 제공하는 lazy를 각각 적용하며 비교해본 결과 router에서 제공하는 방식이 미약하지만 더 크게 최적화를 이룰 수 있었다.

Target Component

 export const loader = () => {}
 export const action = () => {}

 const Service = () => {
	return <> ... </> 
 }
 export default Service

위와 같은 컴포넌트가 존재하고 이 컴포넌트에 lazy loading을 적용해보자

lazy

<Route element={<Layout/>}>
	<Route path='/' element={<Home/>} /> // 홈 화면은 lazy적용 x
	<Route 
    	path='/service'
        lazy={async() => {
        	const module = await import('컴포넌트경로')
            
            return {
            	Component: module.default,
                loader: module.loader,
                action: module.action
              }
        	}
        }
        />
</Route>

이게 전부다.
loader, action, Component까지 전부 한번에 lazy loading을 적용할 수 있다.

fallback같은 경우는 따로 제공하지 않아서 전역적으로 컴포넌트 내부에서 useNavigation훅을 통해 state가 로딩일경우 로딩컴포넌트를 제공하도록 구현할 수 있다.

Dynamic LazyLoader

라우트에서 각각 lazy loading을 적용하고 어떤 컴포넌트는 컴포넌트만 가지고, 어떤 경우는 로더를 포함하는 등 여러 케이스가 존재할 수 있다.
따라서 동적으로 import path만 입력해서 알아서 존재하는 컴포넌트,loader,action을 return하도록 다이나믹한 커스텀함수를 만들어 쓸 수 있다.

type PathType = {
	readonly default: () => JSX.Element
    readonly ErrorBoundary?: ComponentType | null
    laoder?: LoaderFunction
    action?: ActionFunction
}

type LazyResult = () => Promise<{
	readonly default: () => JSX.Element
    readonly ErrorBoundary?: ComponentType | null
}>
	
}

const getLazyLoader = (path : PathType) => {
	const lazyReturn: LazyRouteFunction<NonIndexRouteObject> = async() => {
    const module: LazyResult = await path()
    return {
    	Component: module?.default,
        loader: module?.loader,
        action: module?.action,
        ErrorBoundary: module?.ErrorBoundary
      }
    }
    
    return lazyReturn
}

적용

<Route element={<Layout/>}>
	<Route path='/' element={<Home/>} /> // 홈 화면은 lazy적용 x
	<Route 
    	path='/service'
        lazy={
        	getLazyLoader(
        	 	async() => await import('컴포넌트 절대경로'))
        	}
        />
</Route>

다이나믹 레이지로더 적용 결과 라우트안에서 lazy load가 필요한 컴포넌트를 loader, action을 포함해서 적용시킬 수 있다.

profile
From frontend to fullstack

0개의 댓글