이미지 17.7MB를 830KB로 줄인 방법

메인 화면에 띄울 오브젝트 아트 네 장을 받았다. 배경을 딴 PNG 다. 전부 2816×1536.

용량을 봤다.

Obj_Longshort.png   3.8MB
Obj_Map.png         4.9MB
Obj_braindancer.png 2.4MB
Obj_지금 세계.png    6.6MB

합쳐서 17.7MB. 메인 페이지 첫 화면에 네 장이 전부 뜨는 구조다. 그대로 두면 들어오자마자 17.7MB 를 받는다.

public 과 src

Astro 에서 정적 파일을 두는 곳이 두 군데다.

public/ 은 그대로 복사된다. 빌드가 손대지 않는다. 파비콘이나 robots.txt 처럼 이름과 내용이 그대로 나가야 하는 것들이 여기 있다.

src/ 안에 두고 코드에서 참조하면 빌드가 처리한다. 이미지의 경우 포맷을 바꾸고 크기별로 잘라준다.

받은 파일은 public/media/ 에 있었다. 그래서 손도 안 대고 나가고 있었다.

옮기고 나서

src/assets/objects/ 로 옮기고 <Image> 로 참조하게 바꿨다.

<Image src={artOf(app.art)} alt=""
       widths={[320, 640, 960]}
       sizes="(max-width: 40rem) 45vw, 32rem" />

빌드 로그가 이렇게 나왔다.

counter.jiFn28Kl_Zzkstw.webp   (before: 6757kB, after: 6kB)
counter.jiFn28Kl_jtrTt.webp    (before: 6757kB, after: 832kB)
longshort.C9CmRFu9_1CzO91.webp (before: 3876kB, after: 5kB)
longshort.C9CmRFu9_1uRqti.webp (before: 3876kB, after: 458kB)

한 장에서 여러 크기가 나온다. 브라우저가 화면 크기와 픽셀 밀도를 보고 필요한 것만 받는다. 6.6MB 짜리가 상황에 따라 6KB 에서 832KB 사이로 내려간다.

파일명도 같이 고쳤다

Obj_지금 세계.png 는 한글과 공백이 섞여 있다. 이대로 주소에 넣으면 인코딩이 필요하다.

/media/Obj_%EC%A7%80%EA%B8%88%20%EC%84%B8%EA%B3%84.png

동작은 하는데 깨질 자리가 많다. 서버마다 인코딩 처리가 다르고, 로그에서 읽기도 어렵다. 전부 ASCII 로 바꿨다.

longshort.png  map.png  counter.png  braindancer.png

consts.ts 에서 파일명만 참조하니 이름 바꾸는 비용은 거의 없었다.

결과

첫 로딩이 17.7MB 에서 화면에 따라 수십 KB에서 2MB 안쪽으로 내려갔다. 코드 한 줄 최적화한 게 아니라 파일을 다른 폴더에 둔 결과다.

남은 것

2배 밀도 화면에서는 여전히 오브젝트 하나에 800KB 급을 받는다. 네 장이면 3MB 가까이 된다.

원본을 더 줄여서 넣는 게 맞는지는 아직 안 정했다. 아트는 화면 대부분을 차지하는 주인공이라 화질을 깎기가 망설여진다. 다만 지금은 “일단 큰 걸 넣고 빌드가 알아서 하겠지” 상태라, 어디까지가 적정선인지 재본 적이 없다는 게 마음에 걸린다.

한 가지는 확실하다. public/ 에 무거운 걸 두면 아무도 안 줄여준다. 거기 있는 파일은 빌드 로그에 아예 안 나오니 눈치채기도 어렵다.

← 블로그 목록