본문 바로가기
TIL

이미지 public에 넣기 vs src에 넣고 import하기 ++ 이미지 suspense로 감싸서 가져오기

by 은지:) 2024. 6. 24.
728x90
반응형

 

개발 진행할 때 svg파일 움직일 필요가 있다면 src에 넣고 import 해서 사용했었다

만약 다른 분이 public에 이미 넣어두셨다면 그냥 나도 public에 넣고 썼었음

이미 public에 넣고 쓰시는데... svg 파일을 import해서 가져오려면 설정이 따로 필요했을 뿐더러 이미지 파일 옮기는 것도 일이라 그냥 했음

 

public에 넣으면 따로 압축 과정 안 거치고 빌드 파일에 포함된다는 것까진 알았는데... <= 옛날에 캣보우 때 이거 몰라서 파일 이름 못 찾아 고생함

 

그럼  이미지 public에 넣기 vs src에 넣고 import하기

뭐가 더 좋고 어떤 상황에 맞춰서 써야할까?

 

 

 

chat jpt가 알려준 결론부터 말하자면 이렇게 됨

작은 프로젝트 => public

큰 프로젝트 => src

 

 

public 파일에 넣으면

 

파일 손대지 않고 그대로 빌드되니 추가적인 처리 필요 없음

그러니까 빌드 과정에서 이미지 압축이나 경량화 과정이 빠지니까 빌드 과정을 줄일 수 있음

 

단점은

svg파일을 public에서 가져오게 된다면 결국 

<img src="/images/logo.svg" alt="Company Logo" />

 

이렇게 가져오게 되는데

 

이러면 이미지 가져올 때마다 http 요청 발생함

이미지 파일 많을 경우엔 http 요청 수가 증가해서 로딩 시간 길어질 수 있음

 

 

그럼 src 폴더에 넣게 된다면?

 

svg 파일이 빌드 과정에 들어가게 되어 최적화 가능해짐 (중복 제거나 압축 등)

퍼블릭에서처럼 http로 불러오는게 아니기 때문에 필요할 때만 svg 파일을 로드할 수 있어서 초기 로딩 시간 줄일 수도 있음

 

단점이라면

빌드 크기가 커짐... 이미지까지 포함하니까

당연히 빌드 시간도 늘어남

 

 

 

결론은

 

작은 프로젝트 같은 경우에는 svg 불러와봤자 얼마나 부르겠음

그냥 http로 부름

 

큰 프로젝트는 svg를 동적으로 써야할 경우도 생기기도 하고 일단 import 할 때, 필요한 시점에 로드해서 가져오기 때문에

src에 넣는게 낫다고 함

 

 

 

프로젝트 규모로도 따질 순 있겠지만 나라면 svg 많다면 src에 넣어서 쓰고

아이콘 몇 개 정도라면 public에 넣고 쓸 듯...

 

대신 이미지 보여주는 거 좀 신경 쓰려면

const ImageComponent = ({src}) => {
  return (
    <Suspense fallback={<LoadingComponent />}>
      <img src={src} />
    </Suspense>
  );
};

 

이렇게 쓸 수 있을 거 같다

경로만 받아서 suspense 감쌀 수 있도록...

 

그럼 반대로

src 폴더에 넣고 import 해서 가져올 땐 

 

import React, { Suspense, lazy } from 'react';
import LoadingComponent from './components/LoadingComponent';

const SvgComponent = lazy(() => import('./components/SvgComponent'));

const App = () => {
  return (
    <div>
      <h1>React Suspense SVG Loading</h1>
        <SvgComponent src="./src/images/dynamic-image.svg" alt="이미지 예시"/>
    </div>
  );
};

export default App;

 



const SvgComponent = ({ src, alt = 'SVG Image' }) => {
const DynamicSvg = lazy(() => import(`./src/images/${src}`)
  			       .catch(() => ({ default: () => <div>SVG not found</div> })));

  return (
    <Suspense fallback={<LoadingComponent />}>
      <DynamicSvg />
    </Suspense>
  );
};

 

이렇게 쓸 거 같음

 

 

 

 

 

 

+

저건 svg 파일을 컴포넌트로 가져올 수 있다는 전제하의 예시임

 

-- 필요한 거 --

npm install @svgr/webpack file-loader --save-dev


// 웹팩.config
...............
{
        test: /\.svg$/,
        use: [
          {
            loader: '@svgr/webpack',
            options: {
              icon: true,
            },
          },
          {
            loader: 'file-loader',
            options: {
              name: '[name].[hash].[ext]',
              outputPath: 'assets',
            },
          },

 

 

 

나는 위 과정이 싫다거나 svg 파일을 컴포넌트로 가져올 수 없는 상황이라면

svg를 저장할 때부터 컴포넌트 형식으로 저장시키는 경우도 있을 듯

 

 

app.tsx에서 svg 컴포넌트 불러와 내려주는 방법도 있지만 그건 싫어서

이름 넘겨줌

 

const App = () => {
  return (
    <div>
      <h1>React Suspense SVG Loading</h1>
      <SvgComponent fileName="DynamicImage.tsx" alt="Dynamic SVG" />
      <SvgComponent fileName="AnotherImage.tsx" alt="Another SVG" />
    </div>
  );
};

 


const SvgComponent = ({ fileName, alt = 'SVG Image' }) => {
  const LazyComponent = lazy(() =>
    import(`./src/images/${fileName}`).catch(() => ({
      default: () => <div>SVG not found</div>,
    }))
  );

  return (
    <Suspense fallback={<LoadingComponent />}>
      <LazyComponent />
    </Suspense>
  );
};

 

 

 

 

 

728x90
반응형

'TIL' 카테고리의 다른 글

ts 브랜딩 타입 (태그드 타입) vs enum vs 리터럴  (0) 2024.06.28
jest  (0) 2024.06.26
cra 없이 webpack 개발 환경 설정하기  (0) 2024.06.23
이산수학 필기노트  (0) 2024.06.10
컴퓨터의 이해 필기노트  (0) 2024.06.02

댓글