blog-thumbnail

라우트 기반 코드분할로 로딩 속도 개선하기

React
Code Split
Optimize
Lazy Loading
2023년 4월 15일

create-react-app 기반 웹앱에서 초기 로딩 속도를 개선한 경험에 대해 공유하고자 합니다. (빠른 3G 기준) 처음에는 1.1분이라는 번들 파일 로딩 시간을 코드 분할을 통해 6초로 단축시킨 이야기입니다.

배경 #

웹페이지 로딩 속도는 인터넷 속도가 빠른 사용자에게는 큰 문제가 되지 않지만, 느린 사용자에게는 다릅니다. 특히 모바일 환경에서는 더욱 그렇습니다. 제가 개발중인 서비스의 타겟은 모바일을 사용하는 동남아시아 사람들입니다. 동남아시아에는 빠른 인터넷 환경이 많지 않습니다. 그래서 초기 로딩 속도를 개선하는 것이 더욱 더 중요합니다.

문제 #

3G 환경에서 서비스의 초기 로딩 속도를 테스트 해보니 번들 파일의 크기는 11.3MB, 로딩 속도는 1.1분이었습니다. 이는 사용자가 서비스를 이용하는데 있어서 큰 장애물이 될 수 있습니다.

코드 분할 전 main.js 네트워크 로드코드 분할 전 main.js 네트워크 로드

서비스에서 Phaser를 사용중인데 Bundle 크기가 무려 1.1MB입니다. 일부 페이지에서만 Phaser를 사용하고 있는데 모든 페이지에서 Phaser를 로딩하는 것은 비효율적입니다. 로딩하려는 페이지에서 사용하지 않는 다른 라이브러리도 마찬가지입니다.

bundlephobia에서 Phaser Bundle 크기bundlephobia에서 Phaser Bundle 크기

해결책 - 라우트 기반 코드 분할 #

이 문제를 해결하기 위해 라우트 기반 코드 분할을 도입했습니다. React.lazy()Suspense를 사용하여 라우트별로 코드를 동적으로 로딩할 수 있습니다. 이를 통해 페이지별로 필요한 코드들만 로드되게 하여 초기 로딩 속도를 획기적으로 단축할 수 있었습니다.

import { lazy } from 'react'

export const LandingPage = lazy(() =>
  import('./landing/landingPage').then((m) => ({ default: m.LandingPage })),
)
export const SignInPage = lazy(() =>
  import('./signInPage').then((m) => ({ default: m.SignInPage })),
)

export const HomePage = lazy(() =>
  import('./home/homePage').then((m) => ({ default: m.HomePage })),
)

//...
export const MainRouter = () => {
  //...

  return (
    <Suspense fallback={<LoadingPage />}>
      <Routes>
        <Route path={ROUTE.LANDING} element={<LandingPage />} />
        <Route path={ROUTE.SIGN_IN} element={<SignInPage />} />
        <Route path={ROUTE.HOME} element={<HomePage />} />
        ...
      </Routes>
    </Suspense>
  )
}

위처럼 하게 되면 분할한 코드를 로딩 중일땐 fallback으로 지정한 <LoadingPage/>가 렌더링되고, 로딩이 완료되면 해당 페이지가 렌더링됩니다.

결과 #

코드 분할을 적용한 결과 번들 파일의 크기는 1.1MB에서 0.4MB로 줄었고, 로딩 속도는 1.1분에서 6초로 단축되었습니다.


6초도 여전히 긴 시간이지만 1.1분에 비하면 큰 향상입니다. 사용자가 서비스를 이용하는데 있어서 큰 장애물이 되지 않을 정도로 줄어들었습니다.

CodeSplitSlackMessage

코드 분할 후 main.js 네트워크 로드코드 분할 후 main.js 네트워크 로드

마무리 #

React에서의 코드 분할은 초기 로딩 속도를 효과적으로 개선하는 방법 중 하나입니다.

Next.js에서는 기본으로 제공되는 기능이여서 신경쓸 필요가 없지만, 저의 경험이 create-react-app을 사용하는 팀들에게 도움이 되었으면 좋겠습니다.


감사합니다!


최근 게시물

김진근 • © 2024