Frontend/React

[React] 리액트에서 이미지는 어디서 관리해야할까? (src, public)

양원준 2024. 4. 30. 19:01
728x90

 

리액트에서 이미지를 넣고 싶어 이미지 파일을 첨부할 경우에는 크게

  • public에 넣어 사용하는 방식
  • src에 넣어서 사용하는 방식(보통의 경우 src/assets)

이 있다 

 

나의 경우 src/assets에 넣어 주로 사용하였는데 두 방식이 차이점이 정확하게 무엇인지 모른다는 생각이 들어 알아보기로 했다

 

 

src

  • import할 경우 참조할 수 있는 경로(path) 문자열을 출력한다.
  • 파일을 찾지 못하는 경우, 컴파일 단계에서 에러를 잡을 수 있다(장점)
  • content hash가 파일명에 포함되기 때문에 브라우저가 오래된 버전(파일 수정 전)의 파일을 캐싱하고 있는 경우를 고려하지 않아도 된다. -> 파일이 변경되었을 때만 hash값이 변경된다 (장점)
  • 서버 요청 횟수를 줄이기 위해 10,000 bytes 이하의 이미지는 path대신 data URL을 반환한다.
    (bmp, gif, jpg, jpeg, png 파일에만 적용, SVG 파일 제외)

 

위 특징(장점) 중 content hash에 관한 내용

React 앱을 구축할 때, webpack이나 cra는 일반적으로 자산(예: 이미지, JavaScript 및 CSS 파일)의 번들링 및 최적화를 처리. 
이러한 도구는 해당 자산의 파일 이름에 콘텐츠 해시(파일 콘텐츠를 기반으로 생성되는 고유한 문자열)를 추가한다

[EX: logo.png라는 이름의 이미지]
1. 원본 파일 생성
-빌드 프로세스 중에 이 이미지는 logo.abcdef123456.png와 같은 이름으로 처리되고 이름이 지정
(abcdef123456은 이미지 콘텐츠를 기반으로 생성된 해시)

2. 브라우저 캐싱
-사용자가 애플리케이션을 처음 방문하면 브라우저는 'logo.abcdef123456.png'를 다운로드하여 캐시에 저장
-후속 방문 시 브라우저는 'logo.abcdef123456.png'라는 파일이 이미 있는지 확인하고 다운로드 대신 캐시된 버전 사용

3. 파일 수정(색상이나 크기 변경)
-다음 빌드에서는 이를 반영하기 위해 파일 이름의 해시가 변경
-다시 방문하면 브라우저는 다른 파일 이름을 보고 캐시에 이 파일이 없음을 인식하여 새 버전을 다운로드


따라서,
1)자산이 변경된 경우에만 다운로드하므로 대역폭이 절약되고 로드 시간이 향상
2)브라우저 캐시가 이전 버전의 파일을 보유하고 있기 때문에 사용자가 오래된 콘텐츠를 보는 것과 관련된 문제를 제거
3)파일 이름을 바꾸거나 다른 캐시 무효화 기술을 구현할 필요가 없다
의 장점이 있어 사용자 경험을 향상 시키고 효율적으로 관리 가능해진다

 

사용방법

import와 require를 사용할 수 있다

//1)import 사용
import logo from './assets/logo.png';

function App() {
  return (
    <img src={logo} className='logo' alt='logo' />
  );
}
//2)require 사용
function App2() {
  return (
    <img src={require('./assets/logo.png').default} className='logo' alt='logo' />
  );
}

 

require시 default를 붙히는 이유는 require를 사용하면 객체 형태로 값이 리턴되기 때문에, default 를 붙이면 문자열 형태 그대로 인식되게 만들어주기 때문이다

 

 

 

 

 

public

  • public 폴더는 webpack 에 의해 관리되지 않고, 대신 원본이 build 폴더에 복사
    • 경로가 잘못 되었거나 파일이 없는 경우 컴파일 단계에서 에러가 발생하지 않고, 404에러가 발생
    • 파일명에 content hash가 포함되지 않기 때문에, 파일이 수정될 때 마다 직접 파일명을 수정하거나 매개변수 쿼리를 추가해야함
  • public 폴더에 접근하기 위해서는 PUBLIC_URL 환경변수를 사용해야함

 

사용방법

function App() {
  return (
    <img
      src={`${process.env.PUBLIC_URL}/assets/logo.png`}
      className='logo' alt='logo'
    />
  );
}

 

 

 


결론 : 특별한 경우가 아니라면 src안에서 이미지를 관리하자

 

비교해서 특징 및 장점을 알아보니 딱 알것 같다. 특별한 경우가 아니라면 src폴더에서 이미지를 관리하는게 좋은 듯 싶다

 

public 폴더에서 관리하면

1) 파일이 후처리(post-process)되거나 경량화(minify)되지 않는 문제

2) 컴파일 단계의 오류가 아닌 404 오류가 나는 문제

3) 결과 파일이 수정될 때마다 직접 파일명을 수정하거나 매개변수 쿼리를 추가해야 줘야하는 문제가 있지만

 

 

scr 폴더에서 관리하면
1) path 대신에 data URI 를 리턴해서 서버 요청수를 줄일 수도 있고
2) content hash가 파일명에 포함되어 캐싱을 고려하지 않아도 되고
3) 컴파일 에러를 제공

하기 때문에 src 폴더에서 관리하는 게 좋은 것 같다

 

 

그럼 대체 public은 언제 쓰는게 좋은거지란 생각때문에 좀 찾아보니 아래와 같은 경우가 있다고 한다

  • 특정 이름을 가진 파일이 필요할 때
  • 이미지 파일이 수천 개 있어서 경로를 동적으로 참조해야 할 때
  • 번들링 된 코드 밖에서 pace.js 같은 작은 스크립트를 포함하고 싶을 때
  • webpack과 호환되지 않는 라이브러리를 사용해야 할 때 (<script> 태그로 라이브러리를 포함해야 할 때)

 

추가로 절대경로를 이용할 때 기준은 아래와 같다

  • jsx 파일에서 절대경로는 public 폴더
  • css 파일에서 절대경로는 src 폴더

 

 

 

 

 

728x90

'Frontend > React' 카테고리의 다른 글

[React] useEffect와 라이프 사이클  (0) 2024.05.22
[React] useRef  (0) 2024.05.21
[React] 리액트 폴더구조  (0) 2024.04.23
[React] 보일러 플레이트  (0) 2024.04.18
[React] Props drilling  (0) 2024.04.18