React, SVG 컴포넌트 Lazy Loading

윤태현·약 13시간 전
0

REACT

목록 보기
20/20
post-thumbnail

SVG 파일, React Component로 가져오기 (Vite + TypeScript) 해당 내용의 확장 글입니다.

서론

프로젝트를 진행하면서 아이콘과 같은 SVG 파일을 효율적으로 관리하기 위해 아래와 같은 폴더 구조를 사용했습니다.

📦assets
 ┣ 📂icon
 ┃ ┣ 📜icon-comments.svg
 ┃ ┣ 📜icon-heart.svg
 ┃ ┣ ...
 ┃ ┗ 📜index.ts

index.ts에서 모든 SVG 파일을 React 컴포넌트로 변환 후 한 번에 export를 진행했습니다.

import IconHeart from "./icon-heart.svg?react";
import IconComments from "./icon-comments.svg?react";
...

export {
  IconHeart,
  IconComments,
  ...
}

이렇게 하면서 아이콘 파일들을 일괄적으로 관리하고 각 컴포넌트를 쉽게 가져와 사용할 수 있었습니다.

<IconHeart className="stroke-gray-500" />
<IconComments />


문제점

프로젝트가 커질수록 SVG 파일이 많아지고 아래와 같은 문제들이 발생했습니다.

  • index.ts 파일에서 모든 SVG를 한 번에 import 하여 사용하지 않는 SVG 파일들까지 초기 번들에 포함

  • 특정 페이지에서 사용하지 않는 아이콘들이 불필요하게 로드 되는 상황

  • 아이콘이 많아질수록 index.ts에 모든 아이콘을 관리하기가 힘들어지고 파일을 추가, 삭제할 때마다 빼먹는 경우가 생김



해결 방법

  • 해결하기 위해 Lazy Loading(지연 로딩)을 도입했습니다.
  • 필요한 곳에서만 SVG 아이콘을 불러오도록 진행했습니다.

기존 index.ts 파일을 삭제하고 LazyIcon.tsx 파일을 추가하였습니다.

📦assets
 ┣ 📂icon
 ┃ ┣ 📜icon-comments.svg
 ┃ ┣ 📜icon-heart.svg
 ┃ ┣ ...
 ┃ ┗ 📜LazyIcon.tsx

LazyIcon.tsx

import React, { Suspense } from "react";

type LazyIconProps = {
  name: string;
} & React.SVGProps<SVGSVGElement>;

const LazyIcon = ({ name, ...rest }: LazyIconProps) => {
  const IconComponent = React.lazy(() => import(`./${name}.svg?react`));

  return (
    <Suspense fallback={<div className="h-full w-full animate-pulse bg-gray-100" />}>
      <IconComponent {...rest} />
    </Suspense>
  );
};

export default LazyIcon;
  • React.lazy를 사용해서 SVG 컴포넌트를 동적으로 로드
  • 비동기적으로 로드되므로 로딩 상태를 처리하기 위해 Suspense를 사용

사용 방법

<LazyIcon name="icon-comments" className="~" />


결과

수정 전 (25개 파일 로드) / 용량 : 3.6kB수정 후 (12개 파일 로드) / 용량 : 1.7kB
  • 빨간 박스 : 모든 페이지에서 공통으로 사용하는 SVG
  • 노란 박스 : 현재 페이지에서 사용하는 SVG
  • 그 외 : 다른 곳에서 사용하는 SVG
  • 25개의 SVG 파일에서 현재 페이지에서 사용하고 있는 SVG 파일인 12개의 파일로 줄였습니다.
  • 용량 또한 3.6kB에서 1.7kB로 약 52.8% 감소했습니다.

기존 index.ts 파일로 관리하던 방식은 SVG 파일이 추가, 삭제될 때마다 수정해야 하는 번거로움이 있어 유지보수가 좋지 않았습니다.

모든 곳에서 공통으로 사용하거나 로딩 없이 바로 보여줘야 하는 SVG들만 index.ts에서 관리하고, 그 외에는 각 컴포넌트나 페이지에서 필요한 SVG를 동적 로드하는 방식으로 변경했습니다.

이렇게 하면 SVG 파일의 추가, 삭제가 필요할 때마다 index.ts를 수정할 필요 없이 개별적으로 관리할 수 있어 유지보수성이 향상되고 불필요한 SVG 파일이 초기 번들에 포함되지 않아 번들 사이즈를 줄일 수 있습니다.

0개의 댓글