> For the complete documentation index, see [llms.txt](https://sykim.gitbook.io/music-archiving/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sykim.gitbook.io/music-archiving/next-image.md).

# Next/image 알아보기

Next.js에는 이미지 최적화를 위한 이미지 컴포넌트를 제공하고 있다고 하여 사용해보았다. 근데 어떻게 최적화를 하고 있는 것일까?

{% embed url="<https://nextjs.org/docs/app/building-your-application/optimizing/images>" %}

## 캐싱

이미지가 요청되면, Next.js는 .next/cache/images 폴더 안에 최적화한 이미지를 생성한다. webp 형식으로 저장된 것을 볼 수 있다.

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FtdDJXVn4zMhaeoOjN26Z%2Fimage.png?alt=media&amp;token=40c01459-80b9-4270-a8e6-57087d364ccd" alt=""><figcaption></figcaption></figure>

이때 이미지 요청 결과를 보면, 다음과 같이 Responese Headers에  **X-Nextjs-Cache: MISS**가 적혀있다.

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FcUDDyox6XpVqjpQYR8ah%2Fimage.png?alt=media&amp;token=500b6ba0-8502-4221-a99f-30c531491faa" alt=""><figcaption><p>X-Nextjs-Cache: MISS</p></figcaption></figure>

공식 문서의 설명을 보면, 해당 이미지가 아직 캐싱되지 않은 상태임을 의미한다.&#x20;

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2F1K3p44DHxdZK34fNR8uQ%2Fimage.png?alt=media&amp;token=4f3a53a6-bc40-4de1-92cc-99bdc8517057" alt=""><figcaption></figcaption></figure>

이제 이미지가 캐싱된 상태에서 다시 페이지를 진입했을 때 이미지 요청 결과를 보면, HIT이 적혀있는 것을 볼 수 있다. 캐싱된 이미지를 사용한 것이다.

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FBzvHxHiaxpUYPBuhPzRO%2Fimage.png?alt=media&amp;token=c6f95863-a929-4ac8-91b5-4022f75f409e" alt=""><figcaption></figcaption></figure>

첫 요청(캐싱 X)과 두번째 요청(캐싱 O)를 비교해보면 size, time이 줄어들었다!&#x20;

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FGrKLyq35L3bgJmSHq7cV%2Fimage.png?alt=media&amp;token=2fb13f69-2826-4b97-8d2a-4e8948b4932f" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2F4MiiKkzp6BOmPXefGQSm%2Fimage.png?alt=media&amp;token=77a5e8f0-f2ec-4fc0-83e0-a810ea6e538e" alt=""><figcaption><p>두번 요청 (캐싱  O)</p></figcaption></figure>

## Sizes 설정

이미지 엘리먼트를 확인해보니 sizes에 100vw가 적혀있었다.&#x20;

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FkQxOufRZusN6iK3Lm3ug%2Fimage.png?alt=media&amp;token=627a4eff-05dd-41a6-9096-99ad1dfc7ec8" alt=""><figcaption></figcaption></figure>

공식 문서를 읽어보니, sizes 속성의 기본값은 100vw이다. 브라우저는 페이지에 표시될 이미지의 크기를 아직 모르기 때문에 뷰포트 크기에 해당하는 100vw 크기로 이미지를 다운로드 받는다. sizes 값을 설정하면, 불필요하게 큰 이미지를 다운로드하는 것을 방지할 수 있다.

해당 페이지에서는 뷰포트 크기에 따라 이미지가 2\~4열로 배열된다. 따라서 다음과 같이 적어주었다.&#x20;

```typescript
sizes="(max-width: 376px) 50vw, (max-width: 768px) 33vw, (max-width: 1024px) 25vw, 256px"
```

결과적으로 size도 줄어들었다!

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FK1A1g0J29sc7PMwKZGRQ%2Fimage.png?alt=media&amp;token=31cd7cd2-5f4f-4c9a-b859-87d7f288d539" alt=""><figcaption><p>sizes 설정 &#x26; 첫번째 요청</p></figcaption></figure>

&#x20;

## 배포 환경에서의 캐싱

로컬 환경에서는 최적화된이미지가 프로젝트 폴더 내에 저장되었다. 그럼 배포 환경에서는 캐싱이 어떻게 작동할까? 나의 경우 **Vercel**을 사용해서 배포를 했다.

[공식 문서에 따르면](https://vercel.com/docs/image-optimization) 최적화된 이미지는 Vercel의 Edge Network, Content Delivery Network (CDN)에 캐시된다. &#x20;

&#x20;캐싱된 이미지에 대한 요청을 살펴보면, Response Headers에 **X-Vercel-Cache: HIT**이 적혀있다. (X-Vercel-Cache도 X-Nextjs-Cache와 같이 HIT, STALE, MISS  값을 가진다.)

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FlSF9PZqZxbZkgPLAADnP%2Fimage.png?alt=media&amp;token=17c66422-4c56-445e-b106-48371d7cfb3d" alt=""><figcaption><p>X-Vercel-Cache: HIT</p></figcaption></figure>

## 번외: 브라우저 캐시

요청 결과 size에 memory cache 또는 disk cache가 보일 때가 있다.

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FJjWoyIfRiJnuUBcaDEYI%2Fimage.png?alt=media&amp;token=e7faa25b-4965-47ab-b5da-f777097f5c15" alt=""><figcaption><p>disk cache</p></figcaption></figure>

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FVp6GC50oNvznai0yqPUH%2Fimage.png?alt=media&amp;token=2d72e13b-b423-4892-acc4-9e02ca2a639b" alt=""><figcaption><p>memory cache</p></figcaption></figure>

두가지  캐시 모두 304 응답이 오기 전, 즉 캐시 응답 시간 내 다시 리소스를 요청했을 때 동작한다. 아직 유효한 캐시가 메모리에 남아있기 때문에 메모리 캐시 또는 디스크 캐시로 응답이 가는 것이다.

브라우저는 얼마나 빠르게 리소스를 다시 사용할 가능성에 따라 메모리 or 디스크 캐시를 선택하여 사용한다.&#x20;

캐시 데이터는 하드디스크(HDD)에 저장된다. 하지만 파일 I/O로 인해 처리 속도가 빠르지 않다. 따라서 RAM에 데이터를 저장하여 하드디스크에 접근하는 시간보다 빠르게 접근할 수 있도록 한다.&#x20;

<figure><img src="https://3163604529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHUx5YDKjEwJRrRxG7EnI%2Fuploads%2FDbXIf7tEviX65aXZfA46%2Fimage.png?alt=media&amp;token=e30e4a90-bb59-427f-8306-4a20e7b2e051" alt=""><figcaption></figcaption></figure>

#### memory cache

* RAM(휘발성 메모리)에 저장
* 빠른 속도
* 현재 페이지에서 자주 사용되는 리소스를 저장

#### disk cache

* 하드디스크에 저장
* 상대적으로 느린 속도
* 브라우저를 닫아도 유지됨
* 방문할 가능성이 높은 사이트의 정적 리소스를 저장

## 참고

{% embed url="<https://velog.io/@p-samename/%EC%9B%B9-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-Web-browser-%EC%BA%90%EC%8B%9C-cache>" %}

{% embed url="<https://oliveyoung.tech/2023-06-09/nextjs-image-optimization/>" %}
