코딩하는라민

[React] React.lazy 코드 스플리팅으로 프로젝트 성능 개선하기 본문

Core/React

[React] React.lazy 코드 스플리팅으로 프로젝트 성능 개선하기

코딩하는라민 2023. 4. 18. 10:30
728x90
반응형

[React] React.lazy 코드 스플리팅으로 프로젝트 성능 개선하기

 

📌 React.lazy 함수를 사용하게 된 이유

리액트 프로젝트를 진행하면서 중간중간 Light House 를 이용해 성능 검사를 진행했다.

다른 점수는 항상 90점 이상으로 나왔는데 '성능' 점수만 항상 주황색으로 60~70점 정도가 나왔다.

이 6, 70점도 잘나온 편이었고 정말 성능이 좋지 않은 페이지의 경우에는 4, 50점대까지 나왔다.

성능 최적화는 코드를 작성하고 나서 수행해야 하기 때문에 일단 프로젝트에 집중했고, 추가적으로 성능 개선을 진행하였다.

 

📌 React.lazy 함수란?

React.lazy() 는 동적으로 코드를 로드하고 렌더링할 수 있게 해주는 React의 기능 중 하나이다.

이 기능을 사용하면 일반적인 방식으로 코드를 import 하지만, 실제로 컴포넌트가 사용될 때까지 실제 컴포넌트의 코드를 로드하지 않는다.

 

이러한 코드 스플리팅을 통해 지연 로딩을 도와주고 동적 렌더링을 통해서 페이지의 로드 속도를 개선하여 성능 개선을 할 수 있다.

즉 필요하지 않은 컴포넌트는 불러오지 않아 로딩 시 필요한 비용을 줄여주는 것이다.

규모가 작은 프로젝트에서는 영향이 적겠지만, 프로젝트 규모가 커지면 수많은 컴포넌트를 불러오는데 비용이 어마어마할 것이다.

React.lazy 만 사용해도 점수가 확연히 늘어나는 것을 볼 수 있을 것이다!

 

하지만 React.lazy 는 SSR 을 하지 못하기 때문에 다른 방법을 사용해야한다.

 

📌 import

import { lazy, Suspense } from 'react';

React.lazy() 를 사용할 때, 사용하고자 하는 컴포넌트를 React.Suspense 컴포넌트 안에 렌더링해야한다.

Suspense 컴포넌트는 fallback prop 으로 해당 컴포넌트가 로드되는 동안 로딩 스피너를 보여줄 수 있다.

 

📌 React.lazy 사용하기

✏️ 컴포넌트를 lazy 로드

import Home from './Pages/Home';

🔽

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

 

✏️ 컴포넌트를 Suspense 로 감싸준다.

function App(){
    ...
    return (
        <section>
            <h2>메인 페이지입니다.</h2>
            <Suspense>
                <Home />
            </Suspense>
        </section>
    )
}

 

✏️ fallback prop 추가

function App(){
    ...
    return (
        <section>
            <h2>메인 페이지입니다.</h2>
            <Suspense fallback={<div>페이지를 로딩중입니다. 잠시만 기다려주세요!🐇</div>}>
                <Home />
            </Suspense>
        </section>
    )
}

 

📌 Router 와 함께 사용하기

✏️ import & pages lazy

import { lazy, Suspense } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const App = lazy(() => import("./App"));
const Home = lazy(() => import("./pages/Home"));
const NotFound = lazy(() => import("./components/NotFound"));
const SignIn = lazy(() => import("./pages/SignIn"));
const SignUp = lazy(() => import("./pages/SignUp"));

 

✏️ Router

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    errorElement: <NotFound />,
    children: [
      {
        path: "",
        element: <Home />,
      },
      {
        path: "signin",
        element: <SignIn />,
      },
      {
        path: "signup",
        element: <SignUp />,
      },
    ],
  },
]);

 

✏️ Render

createRoot(document.getElementById("root")).render(
    <Suspense fallback={<div>페이지를 로딩중입니다!🐇</div>}>
      <RouterProvider router={router} />
    </Suspense>
);

 

 

🎹 전체 코드 보기

// 엔트리 파일

import { lazy, Suspense } from "react";
import { createRoot } from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const App = lazy(() => import("./App"));
const Home = lazy(() => import("./pages/Home"));
const NotFound = lazy(() => import("./components/NotFound"));
const SignIn = lazy(() => import("./pages/SignIn"));
const SignUp = lazy(() => import("./pages/SignUp"));

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    errorElement: <NotFound />,
    children: [
      {
        path: "",
        element: <Home />,
      },
      {
        path: "signin",
        element: <SignIn />,
      },
      {
        path: "signup",
        element: <SignUp />,
      },
    ],
  },
]);

createRoot(document.getElementById("root")).render(
    <Suspense fallback={<div>페이지를 로딩중입니다!🐇</div>}>
      <RouterProvider router={router} />
    </Suspense>
);

 

📌 성능 개선 완료된 모습

✏️ 성능 개선 전 : 37점

빌드 전이라 처참한 점수를 보여준다.

그래도 빌드하면 60점대는 될 것...

 

✏️ 1차적으로 main.jsx 파일에 lazy 를 추가해준 성능 : 49점

1차적으로 엔트리 파일에만 lazy 를 추가해준 모습이다.

아직도 성능이 49점이지만, 빌드 전임을 감안한다면 성능이 80점대는 되는 것이다.

이제 App 컴포넌트 내부에도 따로 렌더링해주는 컴포넌트가 있기 때문에 App.jsx 파일에도 lazy 를 추가해줄 것이다.

 

✏️ 2차적으로 App.jsx 파일에 lazy 를 추가해준 성능 : 71점

2차적으로 App.jsx 에 lazy 를 추가해주었다.

App 에 lazy 를 추가하고 Outlet 컴포넌트를 조건부렌더링 하고 있던 것을 그냥 렌더링되도록 고친 것 이 두가지가 성능 점수에 많은 영향을 미쳤었던 것 같다.

 

이대로 빌드하면 90점대는 될 것이다!

 

여기에 이미지 최적화 패키지를 다운받고 추가 최적화를 진행해주면 90점 후반대의 성능을 얻을 수 있을 것이다.

 

 

 

 


참고 : 리액트 공식 문서, ChatGPT
  등을 공부하고, 간단하게 정리한 내용입니다. 잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.

 

728x90
반응형