Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

번들에 코드 스플리팅 적용하기 #481

Closed
Tracked by #476
leegwae opened this issue Oct 17, 2023 · 0 comments
Closed
Tracked by #476

번들에 코드 스플리팅 적용하기 #481

leegwae opened this issue Oct 17, 2023 · 0 comments

Comments

@leegwae
Copy link
Member

leegwae commented Oct 17, 2023

🤸‍♂️ 목표

SVG-in-JS를 제거하여 번들 크기를 줄이고 @import를 제거하여 초기 로딩 시간도 단축했지만 아직 성능 점수는 80점이다. 가장 큰 영향을 미치는 건 역시 자바스크립트 번들이다.

image

번들의 크기를 줄이는 것(Minification)에는 다음과 같은 방법이 있다. 흔히 다음과 같은 방법을 사용한다.

  1. 트리쉐이킹: 사용하지 않는 코드를 제거한다.
  2. 압축: gzip과 같은 확장자를 사용하여 압축한다.
  3. 코드 스플리팅: 코드를 분할하여 현재 필요한 모듈만 다운로드한다.
  4. minify: 공백, 주석을 삭제하거나 변수 이름을 축약한다.

트리쉐이킹은 vite가 알아서 해준다. 압축은 다음 이슈에서 ngnix에 설정해볼 거다. minify도 vite가 알아서 해준다. 이번 이슈에서는 코드 스플리팅을 통해 자바스크립트 번들 크기를 줄여보겠다.

image

✨ React Router v6.4 lazy를 사용한 지연 로딩 및 코드 스플리팅

참고
https://remix.run/blog/lazy-loading-routes
https://reactrouter.com/en/main/route/lazy

React.lazy를 사용하면 컴포넌트를 렌더링한 후 데이터를 페칭하지만, React Router의 lazy를 사용하면 라우팅이 된 시점에 데이터를 페칭해 와 최종적으로 데이터가 로딩된 컴포넌트를 렌더링할 수 있다.

// pages/Home.tsx
export loader = () => {};
export Component() {}
export ErrorBoundary() {}
import { createBrowserRouter } from 'react-router-dom';

const router = createBrowserRouter([
  {
    path: "/",
    element: <Layout />,
    children: [
      {
        path: "home",
        lazy: async () => import("./pages/Home"),
      },
    ],
  },
]);

lazy가 반환하는 객체의 프로퍼티는 loader, Component, ErrorBoundary`여야한다. 그러니 다른 이름으로 내보낸 경우 다음과 같이 처리해주면 된다.

{
  lazy: async () => {
    const { homeLoader, ...rest } = await import("./pages/Home");
    return { ...rest, loader: homeLoader };
  };
}

현재 경로 중에서 인덱스, 로그인, 회원가입 페이지를 제외하고 lazy를 적용해보았다.

image

index.js 번들 사이즈가 약 70kb 줄었다. 라이트하우스 지표를 알아보자.

image

80점에서 87점으로 대폭 개선되었다!



(해결중) ✨ 모듈 코드 스플리팅하기

페이지 코드만 분할할 수 있는 게 아니라, 외부 모듈도 분할할 수 있다. toquiz는 vite를 사용하므로 Rollup Plugin Visualizer로 어느 모듈이 번들에서 큰 크기를 사용하고 있는지 알아보자.

image

눈에 띄는 것은 @remix-run/router와 react-dom, sockjs-client와 @stomp/stompjs이다. 라우터는 라우팅이 필요한 시점부터 필요하고 socket은 패널 페이지에서만 필요하다(아니다 루트부터 사용한다). 이들을 index.js 번들에서 떼어보자.

image

Total Blocking Time은 0ms으로 줄었는데 성능 점수가 낮아졌다. 아무래도 직접 chunk를 만드는 건 세심하게 해봐야겠다.

참고

@leegwae leegwae self-assigned this Oct 17, 2023
leegwae added a commit that referenced this issue Oct 17, 2023
@leegwae leegwae closed this as completed Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant