본문 바로가기

카테고리 없음

[React] 코드 스플리팅과 지연 로딩을 통한 초기 로딩 성능 개선

반응형

웹 애플리케이션의 규모가 커질수록 초기 로딩 시간도 함께 늘어나게 됩니다. 사용자들은 빠른 로딩 속도를 기대하기 때문에, 초기 로딩 성능을 개선하는 것은 매우 중요합니다. 이번 블로그에서는 React 애플리케이션의 초기 로딩 성능을 개선하기 위한 두 가지 핵심 기술인 코드 스플리팅(Code Splitting)과 지연 로딩(Lazy Loading)에 대해 알아보겠습니다.

1. 코드 스플리팅이란?

코드 스플리팅은 애플리케이션의 코드를 여러 개의 작은 번들로 나누는 기술입니다. 이를 통해 필요한 코드만 로드하고 실행할 수 있어, 초기 로딩 시간을 단축시킬 수 있습니다.

왜 코드 스플리팅이 필요한가?

일반적으로 React 애플리케이션을 빌드하면 모든 코드가 하나의 큰 JavaScript 파일(번들)로 만들어집니다. 이 방식의 문제점은 다음과 같습니다:

  1. 초기 로딩 시간 증가: 사용자가 첫 페이지를 로드할 때 전체 애플리케이션 코드를 다운로드해야 합니다.
  2. 불필요한 리소스 사용: 당장 필요하지 않은 코드까지 로드하게 됩니다.
  3. 성능 저하: 큰 JavaScript 파일을 파싱하고 실행하는 데 시간이 더 오래 걸립니다.

코드 스플리팅을 사용하면 이러한 문제를 해결할 수 있습니다.

2. 지연 로딩이란?

지연 로딩은 필요한 시점에 코드를 로드하는 기술입니다. React에서는 React.lazySuspense를 사용하여 구현할 수 있습니다.

코드 스플리팅과 지연 로딩의 관계

코드 스플리팅이 코드를 여러 조각으로 나누는 기술이라면, 지연 로딩은 이렇게 나눈 코드를 필요한 시점에 로드하는 기술입니다. 두 기술은 함께 사용되어 초기 로딩 성능을 크게 개선할 수 있습니다.

3. React에서의 구현 방법

3.1 동적 import()

React에서 가장 기본적인 코드 스플리팅 방법은 동적 import() 문을 사용하는 것입니다.

import("./math").then(math => {
  console.log(math.add(16, 26));
});

이 방식을 사용하면 해당 모듈이 필요한 시점에 비동기적으로 로드됩니다.

3.2 React.lazy와 Suspense

React는 컴포넌트 레벨에서의 코드 스플리팅을 위해 React.lazySuspense를 제공합니다.

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

이 예제에서 OtherComponent는 이 컴포넌트가 처음 렌더링될 때만 로드됩니다. Suspense 컴포넌트는 OtherComponent가 로드되는 동안 보여줄 로딩 UI를 지정할 수 있게 해 줍니다.

4. 실제 적용 사례

4.1 라우트 기반 코드 스플리팅

가장 일반적인 코드 스플리팅 적용 사례는 라우트 별로 코드를 나누는 것입니다.

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 Contact = lazy(() => import('./routes/Contact'));

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

이 방식을 사용하면 각 라우트에 해당하는 컴포넌트는 해당 경로로 이동할 때만 로드됩니다.

4.2 컴포넌트 레벨 코드 스플리팅

때로는 특정 컴포넌트가 무거운 경우 해당 컴포넌트만 따로 분리할 수 있습니다.

const LargeComponent = lazy(() => import('./LargeComponent'));

function MyComponent() {
  const [showLargeComponent, setShowLargeComponent] = useState(false);

  return (
    <div>
      <button onClick={() => setShowLargeComponent(true)}>
        Show Large Component
      </button>
      {showLargeComponent && (
        <Suspense fallback={<div>Loading...</div>}>
          <LargeComponent />
        </Suspense>
      )}
    </div>
  );
}

이 예제에서 LargeComponent는 버튼을 클릭해 showLargeComponenttrue가 될 때만 로드됩니다.

5. 성능 측정 및 최적화

코드 스플리팅과 지연 로딩을 적용한 후에는 실제로 성능이 개선되었는지 확인해야 합니다.

5.1 성능 측정 도구

  • Chrome DevTools의 Network 탭: 각 JavaScript 파일의 로드 시간을 확인할 수 있습니다.
  • Lighthouse: 웹 페이지의 전반적인 성능을 측정할 수 있습니다.
  • React DevTools의 Profiler: React 컴포넌트의 렌더링 성능을 측정할 수 있습니다.

5.2 추가 최적화 팁

  1. 적절한 스플리팅 포인트 선택: 너무 작은 단위로 나누면 오히려 HTTP 요청이 많아져 성능이 저하될 수 있습니다.
  2. 프리로딩 활용: 사용자가 특정 액션을 취할 가능성이 높은 경우, 미리 해당 코드를 로드할 수 있습니다.
  3. 캐싱 전략 수립: 효과적인 캐싱 전략을 통해 한 번 로드한 코드를 재사용할 수 있습니다.

코드 스플리팅과 지연 로딩은 React 애플리케이션의 초기 로딩 성능을 크게 개선할 수 있는 강력한 도구입니다. 하지만 무조건적인 적용보다는 애플리케이션의 특성과 사용자의 행동 패턴을 고려하여 적절히 적용하는 것이 중요합니다.

 

또한, 성능 최적화는 지속적인 과정이라는 점을 명심해야 합니다. 코드 스플리팅과 지연 로딩을 적용한 후에도 꾸준히 성능을 모니터링하고, 필요에 따라 최적화 전략을 조정해 나가는 것이 좋습니다.

 

마지막으로, 웹 성능 최적화는 코드 스플리팅과 지연 로딩 외에도 다양한 기법이 있습니다.

이미지 최적화, 서버 사이드 렌더링, 효율적인 상태 관리 등 다른 최적화 기법들과 함께 사용한다면 더욱 빠르고 반응성 좋은 React 애플리케이션을 만들 수 있을 것입니다.

반응형