이미지 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/ 에 무거운 걸 두면 아무도 안 줄여준다. 거기 있는 파일은 빌드 로그에 아예 안 나오니 눈치채기도 어렵다.