[๐Ÿค–] Next.js Image ์ปดํฌ๋„ŒํŠธ ์ตœ์ ํ™”: Core Web Vitals ๊ฐœ์„ ๋ถ€ํ„ฐ ์‹ค์ „ ํ™œ์šฉ๊นŒ์ง€

Next.js์˜ Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์›น ์„ฑ๋Šฅ ํ•ต์‹ฌ ์ง€ํ‘œ์ธ Core Web Vitals๋ฅผ ๊ฐœ์„ ํ•˜๊ณ , ๋‹ค์–‘ํ•œ ์ตœ์ ํ™” ์˜ต์…˜์„ ์‹ค์ „ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ธ”๋ฃจ๊ฐ€ ์ž์„ธํžˆ ์•Œ๋ ค๋“œ๋ ค์š”.

22๋ถ„
๋‹จ์–ด: 1,932๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

Next.js Image ์ปดํฌ๋„ŒํŠธ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๋‹ค์–‘ํ•œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์„ ์ตํ˜€ ์›น ์„ฑ๋Šฅ ์ง€ํ‘œ(Core Web Vitals)๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ด์š”.

์•ˆ๋…•ํ•˜์„ธ์š”! 10๋…„ ์ด์ƒ ๊ฒฝ๋ ฅ์˜ ์‹œ๋‹ˆ์–ด ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž์ด์ž ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ SEO ์ „๋ฌธ๊ฐ€, ๋ธ”๋ฃจ์˜ˆ์š”. ์ €๋Š” ์‹ค์ œ ์กด์žฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋Š” ์•„๋‹ˆ์ง€๋งŒ, ์—ฌ๋Ÿฌ๋ถ„์˜ ์›น ๊ฐœ๋ฐœ ์—ฌ์ •์— ์‹ค์งˆ์ ์ธ ๋„์›€์„ ๋“œ๋ฆฌ๊ณ ์ž ์ด ์ž๋ฆฌ์— ์™”์–ด์š”. ์˜ค๋Š˜์€ Next.js ํ”„๋กœ์ ํŠธ์—์„œ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ์›น ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”ํ•˜๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊นŠ์ด ์žˆ๊ฒŒ ๋‹ค๋ค„๋ณด๋ ค๊ณ  ํ•ด์š”. ํŠนํžˆ Core Web Vitals ์ง€ํ‘œ ๊ฐœ์„ ์— ์ดˆ์ ์„ ๋งž์ถฐ ์‹ค์ „ ํŒ์„ ๋งŽ์ด ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”.

๐Ÿ–ผ๏ธ ์›น ์ด๋ฏธ์ง€, ์™œ ์ค‘์š”ํ• ๊นŒ์š”?

์›น ํŽ˜์ด์ง€์—์„œ ์ด๋ฏธ์ง€๋Š” ์‹œ๊ฐ์ ์ธ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ’๋ถ€ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ํ•ต์‹ฌ ์š”์†Œ์˜ˆ์š”. ํ•˜์ง€๋งŒ ์ž˜๋ชป ๊ด€๋ฆฌ๋œ ์ด๋ฏธ์ง€๋Š” ์›น ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์ฃผ๋ฒ”์ด ๋˜๊ธฐ๋„ ํ•œ๋‹ต๋‹ˆ๋‹ค.

0๏ธโƒฃ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”๊ฐ€ ์›น ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ

๊ตฌ๊ธ€์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉฐ, ์ด๋ฅผ ์ธก์ •ํ•˜๋Š” ํ•ต์‹ฌ ์ง€ํ‘œ๋กœ Core Web Vitals๋ฅผ ์ œ์‹œํ•˜๊ณ  ์žˆ์–ด์š”. ์ด ์ง€ํ‘œ๋“ค์€ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์„ฑ๋Šฅ, ์ƒํ˜ธ์ž‘์šฉ์„ฑ, ์‹œ๊ฐ์  ์•ˆ์ •์„ฑ์„ ์ธก์ •ํ•˜๋Š”๋ฐ์š”. ์ด๋ฏธ์ง€๋Š” ์ด ์ง€ํ‘œ๋“ค์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์ณ์š”.

  • LCP (Largest Contentful Paint): ํŽ˜์ด์ง€์˜ ๊ฐ€์žฅ ํฐ ์ฝ˜ํ…์ธ  ์š”์†Œ๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ์‹œ๊ฐ„์„ ์ธก์ •ํ•ด์š”. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, ํŽ˜์ด์ง€์—์„œ ๊ฐ€์žฅ ํฐ ์ฝ˜ํ…์ธ ๋Š” ์ด๋ฏธ์ง€์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์š”. ์ตœ์ ํ™”๋˜์ง€ ์•Š์€ ํฐ ์ด๋ฏธ์ง€๋Š” LCP๋ฅผ ์ง€์—ฐ์‹œ์ผœ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ต๋‹ตํ•จ์„ ์ค„ ์ˆ˜ ์žˆ์–ด์š”.
  • CLS (Cumulative Layout Shift): ํŽ˜์ด์ง€ ์ฝ˜ํ…์ธ ์˜ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ ˆ์ด์•„์›ƒ ์ด๋™๋Ÿ‰์„ ์ธก์ •ํ•ด์š”. ์ด๋ฏธ์ง€์˜ width์™€ height ์†์„ฑ์ด ์ง€์ •๋˜์ง€ ์•Š์œผ๋ฉด, ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋œ ํ›„ ๊ฐ‘์ž๊ธฐ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๋ฉฐ ์ฃผ๋ณ€ ์ฝ˜ํ…์ธ ๋ฅผ ๋ฐ€์–ด๋‚ด๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์‹ฌ๊ฐํ•˜๊ฒŒ ํ•ด์น  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.
  • FCP (First Contentful Paint): ์ฒซ ๋ฒˆ์งธ ์ฝ˜ํ…์ธ  ์š”์†Œ๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ์‹œ๊ฐ„์„ ์ธก์ •ํ•ด์š”. ์ด๋ฏธ์ง€ ๋กœ๋”ฉ์ด ๋А๋ฆฌ๋ฉด FCP๋„ ํ•จ๊ป˜ ์ง€์—ฐ๋  ์ˆ˜ ์žˆ์–ด์š”.

์ด์ฒ˜๋Ÿผ ์ด๋ฏธ์ง€๋ฅผ ์ œ๋Œ€๋กœ ์ตœ์ ํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒ€์ƒ‰ ์—”์ง„ ์ˆœ์œ„์—๋„ ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ , ๊ฒฐ๊ตญ ์‚ฌ์šฉ์ž ์ดํƒˆ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ผญ ๊ธฐ์–ตํ•ด์•ผ ํ•ด์š”.

1๏ธโƒฃ ๊ธฐ์กด ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์˜ ํ•œ๊ณ„

๊ธฐ์กด ์›น ๊ฐœ๋ฐœ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ํ”ํžˆ ๊ฒช๋Š” ๋ฌธ์ œ์ ๋“ค์ด ๋งŽ์•„์š”. ์ผ์ผ์ด ์ˆ˜์ž‘์—…์œผ๋กœ ์ตœ์ ํ™”ํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์‹ค์ˆ˜ํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ๋†’์•˜์–ด์š”.

  • ์ˆ˜๋™ ์ตœ์ ํ™”์˜ ์–ด๋ ค์›€: ๊ฐ ๊ธฐ๊ธฐ ํ•ด์ƒ๋„์— ๋งž๋Š” ๋‹ค์–‘ํ•œ ํฌ๊ธฐ์˜ ์ด๋ฏธ์ง€๋ฅผ ์ค€๋น„ํ•˜๊ณ , ์ตœ์‹  ์ด๋ฏธ์ง€ ํฌ๋งท(WebP, AVIF)์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…์€ ๋งŽ์€ ์‹œ๊ฐ„๊ณผ ๋…ธ๋ ฅ์„ ํ•„์š”๋กœ ํ•ด์š”.
  • ๋ ˆ์ด์ง€ ๋กœ๋”ฉ ๊ตฌํ˜„์˜ ๋ฒˆ๊ฑฐ๋กœ์›€: ํ™”๋ฉด์— ๋ณด์ด๋Š” ์ด๋ฏธ์ง€๋ถ€ํ„ฐ ๋กœ๋“œํ•˜๊ณ  ๋ณด์ด์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€๋Š” ๋‚˜์ค‘์— ๋กœ๋“œํ•˜๋Š” ๋ ˆ์ด์ง€ ๋กœ๋”ฉ(Lazy Loading)์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด Intersection Observer API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ๋˜ํ•œ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ถ€๋‹ด์ด ๋  ์ˆ˜ ์žˆ์–ด์š”.
  • CLS ๋ฌธ์ œ: <img> ํƒœ๊ทธ์— width์™€ height๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด, ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๋ฅผ ์•Œ ์ˆ˜ ์—†์–ด ๋ ˆ์ด์•„์›ƒ ์‰ฌํ”„ํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์› ์–ด์š”.
  • ์„ฑ๋Šฅ ์ธก์ • ๋ฐ ๊ฐœ์„ ์˜ ์–ด๋ ค์›€: ์–ด๋–ค ์ด๋ฏธ์ง€๊ฐ€ LCP์— ๊ฐ€์žฅ ํฐ ์˜ํ–ฅ์„ ์ฃผ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ณ  ๊ฐœ์„ ํ•˜๋Š” ๊ณผ์ •์ด ์ง๊ด€์ ์ด์ง€ ์•Š์•˜์–ด์š”.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Next.js์—์„œ๋Š” ๊ฐ•๋ ฅํ•œ Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด์š”.

โœจ Next.js Image ์ปดํฌ๋„ŒํŠธ์˜ ๋งˆ๋ฒ•

Next.js Image ์ปดํฌ๋„ŒํŠธ(next/image)๋Š” ์ด๋Ÿฌํ•œ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”์˜ ์–ด๋ ค์›€์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํƒ„์ƒํ–ˆ์–ด์š”. ๋นŒ๋“œ ์‹œ์  ๋˜๋Š” ์š”์ฒญ ์‹œ์ ์— ์ด๋ฏธ์ง€๋ฅผ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•˜์—ฌ ์„ฑ๋Šฅ๊ณผ ๊ฐœ๋ฐœ ํŽธ์˜์„ฑ์„ ๋™์‹œ์— ์žก์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ์ฃ .

0๏ธโƒฃ ์ž๋™์œผ๋กœ ์–ป๋Š” ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ

Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์ž๋™์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”.

  • ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€: ๊ธฐ๊ธฐ ๋„ˆ๋น„์— ๋”ฐ๋ผ ์ตœ์ ํ™”๋œ ํฌ๊ธฐ์˜ ์ด๋ฏธ์ง€๋ฅผ ์ œ๊ณตํ•ด์š”.
  • ์ด๋ฏธ์ง€ ํฌ๋งท ์ตœ์ ํ™”: WebP, AVIF์™€ ๊ฐ™์€ ์ตœ์‹  ์ด๋ฏธ์ง€ ํฌ๋งท์œผ๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•˜์—ฌ ํŒŒ์ผ ํฌ๊ธฐ๋ฅผ ์ค„์—ฌ์ค˜์š” (๋ธŒ๋ผ์šฐ์ € ์ง€์› ์—ฌ๋ถ€์— ๋”ฐ๋ผ).
  • ๋ ˆ์ด์ง€ ๋กœ๋”ฉ: ๋ทฐํฌํŠธ ๋ฐ–์— ์žˆ๋Š” ์ด๋ฏธ์ง€๋Š” ์ž๋™์œผ๋กœ ์ง€์—ฐ ๋กœ๋“œํ•˜์—ฌ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œ์ผœ์š”.
  • CLS ๋ฐฉ์ง€: width์™€ height ์†์„ฑ์„ ํ•„์ˆ˜๋กœ ์š”๊ตฌํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋กœ๋“œ ์ „ ๋ ˆ์ด์•„์›ƒ ๊ณต๊ฐ„์„ ํ™•๋ณด, CLS๋ฅผ ๋ฐฉ์ง€ํ•ด์š”.
  • ์™ธ๋ถ€ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”: next.config.js ์„ค์ •์„ ํ†ตํ•ด ์™ธ๋ถ€ ์ด๋ฏธ์ง€๋„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ด ๋ชจ๋“  ๊ฒƒ์ด <img> ํƒœ๊ทธ ๋Œ€์‹  <Image /> ์ปดํฌ๋„ŒํŠธ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค๋Š” ์ ์ด ์ •๋ง ๋งค๋ ฅ์ ์ด์—์š”.

1๏ธโƒฃ ํ•ต์‹ฌ ์†์„ฑ ํŒŒํ—ค์น˜๊ธฐ: src, width, height, alt

Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์†์„ฑ๋“ค์ด์—์š”.

  • src: ์ด๋ฏธ์ง€ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์š”. ๋กœ์ปฌ ์ด๋ฏธ์ง€๋Š” import ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ์‚ฌ์šฉํ•˜๊ณ , ์™ธ๋ถ€ ์ด๋ฏธ์ง€๋Š” URL ๋ฌธ์ž์—ด๋กœ ์ง€์ •ํ•ด์š”.
  • width, height: ์ด๋ฏธ์ง€์˜ ์›๋ณธ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ์ง€์ •ํ•ด์š”. ์ด ์†์„ฑ๋“ค์€ CLS๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์ˆ˜์ ์ด์—์š”. fill ์†์„ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ด ๋‘ ์†์„ฑ์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • alt: ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์ œ๊ณตํ•˜๋Š” ๋Œ€์ฒด ํ…์ŠคํŠธ์˜ˆ์š”. ์›น ์ ‘๊ทผ์„ฑ(Accessibility)์„ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•ด์•ผ ํ•˜๋Š” ํ•„์ˆ˜ ์†์„ฑ์ด๋ž๋‹ˆ๋‹ค.
import Image from 'next/image'; import myLocalImage from '../public/my-local-image.jpg'; // ๋กœ์ปฌ ์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ export default function BasicImageUsage() { return ( <div> {/* ๋กœ์ปฌ ์ด๋ฏธ์ง€ ์‚ฌ์šฉ ์˜ˆ์‹œ */} <Image src={myLocalImage} alt="์•„๋ฆ„๋‹ค์šด ์ž์—ฐ ํ’๊ฒฝ" width={500} // ์ด๋ฏธ์ง€์˜ ์›๋ณธ ๋„ˆ๋น„ height={300} // ์ด๋ฏธ์ง€์˜ ์›๋ณธ ๋†’์ด /> {/* ์™ธ๋ถ€ ์ด๋ฏธ์ง€ ์‚ฌ์šฉ ์˜ˆ์‹œ (next.config.js ์„ค์ • ํ•„์š”) */} <Image src="https://example.com/remote-image.jpg" alt="์›๊ฒฉ ์„œ๋ฒ„์˜ ์ด๋ฏธ์ง€" width={600} height={400} /> </div> ); }

2๏ธโƒฃ ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€๋ฅผ ์œ„ํ•œ sizes ์†์„ฑ

sizes ์†์„ฑ์€ ๋ธŒ๋ผ์šฐ์ €์— ๋ทฐํฌํŠธ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์–ด๋–ค ํฌ๊ธฐ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•ด์•ผ ํ•˜๋Š”์ง€ ํžŒํŠธ๋ฅผ ์ œ๊ณตํ•ด์š”. ์ด๋ฅผ ํ†ตํ•ด ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ฐ€์žฅ ์ ์ ˆํ•œ srcset์„ ์„ ํƒํ•˜์—ฌ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ํฐ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ , LCP ๊ฐœ์„ ์— ๋„์›€์„ ์ค˜์š”.

sizes๋Š” ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ ์กฐ๊ฑด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฏธ์ง€์˜ ์ตœ์ข… ๋ Œ๋”๋ง ํฌ๊ธฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฌธ์ž์—ด์ด์—์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜๋ฏธ๋ฅผ ๊ฐ€์ ธ์š”.

  • ๋ทฐํฌํŠธ ๋„ˆ๋น„๊ฐ€ 768px ์ดํ•˜์ผ ๋•Œ: ์ด๋ฏธ์ง€ ๋„ˆ๋น„๋Š” ๋ทฐํฌํŠธ ๋„ˆ๋น„์˜ 100%
  • ๋ทฐํฌํŠธ ๋„ˆ๋น„๊ฐ€ 768px ์ดˆ๊ณผ 1200px ์ดํ•˜์ผ ๋•Œ: ์ด๋ฏธ์ง€ ๋„ˆ๋น„๋Š” ๋ทฐํฌํŠธ ๋„ˆ๋น„์˜ 50%
  • ๋ทฐํฌํŠธ ๋„ˆ๋น„๊ฐ€ 1200px ์ดˆ๊ณผ์ผ ๋•Œ: ์ด๋ฏธ์ง€ ๋„ˆ๋น„๋Š” ๋ทฐํฌํŠธ ๋„ˆ๋น„์˜ 33%

fill ์†์„ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด width, height๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ๋ถ€๋ชจ ์š”์†Œ์— ๊ฝ‰ ์ฑ„์šฐ๋Š” ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•ด์š”.

3๏ธโƒฃ LCP ๊ฐœ์„ ์„ ์œ„ํ•œ priority์™€ placeholder

  • priority: true๋กœ ์„ค์ •ํ•˜๋ฉด ์ด๋ฏธ์ง€๊ฐ€ LCP ์š”์†Œ๋กœ ๊ฐ„์ฃผ๋˜์–ด, ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋ณด๋‹ค ๋จผ์ € ๋กœ๋“œ๋˜๋„๋ก ์ตœ์ ํ™”๋ผ์š”. ๋ทฐํฌํŠธ ๋‚ด์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ด๋ฏธ์ง€(์˜ˆ: ํžˆ์–ด๋กœ ์ด๋ฏธ์ง€)์—๋งŒ priority๋ฅผ true๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”. ๋‚จ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์— ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด์š”.
  • placeholder: ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ๋ณด์—ฌ์ค„ ์ž„์‹œ UI๋ฅผ ์„ค์ •ํ•ด์š”. blur ๋˜๋Š” empty ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์š”. blur๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด blurDataURL ์†์„ฑ์„ ํ†ตํ•ด ํ๋ฆฟํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์—ฌ์ฃผ์–ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”.
import Image from 'next/image'; import heroImage from '../public/hero-image.jpg'; // LCP ๋Œ€์ƒ ์ด๋ฏธ์ง€ export default function LCPImageExample() { return ( <div> {/* LCP ๊ฐœ์„ ์„ ์œ„ํ•œ ํžˆ์–ด๋กœ ์ด๋ฏธ์ง€ */} <Image src={heroImage} alt="๋ฉ”์ธ ํŽ˜์ด์ง€์˜ ์ค‘์š”ํ•œ ์ด๋ฏธ์ง€" width={1920} height={1080} priority={true} // ์ด ์ด๋ฏธ์ง€๋ฅผ ์ตœ์šฐ์„ ์œผ๋กœ ๋กœ๋“œํ•ด์š” placeholder="blur" // ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „ ํ๋ฆฟํ•œ ํšจ๊ณผ๋ฅผ ๋ณด์—ฌ์ค˜์š” /> {/* ์ผ๋ฐ˜ ์ด๋ฏธ์ง€ (๋ ˆ์ด์ง€ ๋กœ๋”ฉ ๊ธฐ๋ณธ ์ ์šฉ) */} <Image src="/secondary-image.jpg" // public ํด๋” ์ด๋ฏธ์ง€ alt="๋ถ€๊ฐ€์ ์ธ ์ด๋ฏธ์ง€" width={800} height={600} /> </div> ); }

4๏ธโƒฃ ์›๊ฒฉ ์ด๋ฏธ์ง€ ๋ฐ ์ปค์Šคํ…€ ๋กœ๋” ์„ค์ •

๊ธฐ๋ณธ์ ์œผ๋กœ Next.js Image ์ปดํฌ๋„ŒํŠธ๋Š” ๋กœ์ปฌ ์ด๋ฏธ์ง€์™€ public ํด๋” ๋‚ด์˜ ์ด๋ฏธ์ง€๋ฅผ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•ด์š”. ์™ธ๋ถ€ URL์˜ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด next.config.js ํŒŒ์ผ์— ํ•ด๋‹น ๋„๋ฉ”์ธ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ด์š”.

// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { images: { domains: ['example.com', 'another-domain.com'], // ์™ธ๋ถ€ ์ด๋ฏธ์ง€ ๋„๋ฉ”์ธ ๋“ฑ๋ก // ๋˜๋Š” remotePatterns ์‚ฌ์šฉ (๊ถŒ์žฅ) // remotePatterns: [ // { // protocol: 'https', // hostname: 'assets.example.com', // port: '', // pathname: '/my-assets/**', // }, // ], }, }; module.exports = nextConfig;

๋˜ํ•œ, ์ด๋ฏธ์ง€ CDN(์˜ˆ: Cloudinary, Imgix)์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํŠน์ • ๋กœ์ง์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•ด์•ผ ํ•  ๊ฒฝ์šฐ, loader ์†์„ฑ์ด๋‚˜ next.config.js์˜ images.loader ์„ค์ •์„ ํ†ตํ•ด ์ปค์Šคํ…€ ๋กœ๋”๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด์š”.

// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { images: { loader: 'custom', // ์ปค์Šคํ…€ ๋กœ๋” ์‚ฌ์šฉ์„ ๋ช…์‹œํ•ด์š” loaderFile: './my-image-loader.js', // ์ปค์Šคํ…€ ๋กœ๋” ํŒŒ์ผ ๊ฒฝ๋กœ }, }; module.exports = nextConfig; // my-image-loader.js (์˜ˆ์‹œ) export default function myImageLoader({ src, width, quality }) { const url = new URL(src); url.searchParams.set('w', width.toString()); url.searchParams.set('q', (quality || 75).toString()); return url.href; }

๐Ÿš€ ์‹ค์ „ ์ฝ”๋“œ ์˜ˆ์‹œ๋กœ ๋ฐฐ์šฐ๋Š” Image ์ปดํฌ๋„ŒํŠธ ํ™œ์šฉ

์ด์ œ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด Image ์ปดํฌ๋„ŒํŠธ์˜ ๋‹ค์–‘ํ•œ ํ™œ์šฉ๋ฒ•์„ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

0๏ธโƒฃ ๊ธฐ๋ณธ์ ์ธ ์ด๋ฏธ์ง€ ์‚ฌ์šฉ๋ฒ•

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋กœ์ปฌ ์ด๋ฏธ์ง€ ์‚ฌ์šฉ ์˜ˆ์‹œ์˜ˆ์š”. width์™€ height๋ฅผ ๋ช…์‹œํ•˜์—ฌ CLS๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ , ์ž๋™์œผ๋กœ ๋ ˆ์ด์ง€ ๋กœ๋”ฉ๊ณผ ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•ด์š”.

// components/MyProductImage.tsx import Image from 'next/image'; import productThumbnail from '@/public/product-thumbnail.jpg'; // @/public๋Š” alias ์„ค์ • ๊ฐ€์ • interface MyProductImageProps { altText: string; } export default function MyProductImage({ altText }: MyProductImageProps) { return ( <div style={{ position: 'relative', width: '200px', height: '150px' }}> <Image src={productThumbnail} alt={altText} width={200} // ์›๋ณธ ์ด๋ฏธ์ง€์˜ ๋„ˆ๋น„๋ฅผ ์ง€์ •ํ•ด์š” height={150} // ์›๋ณธ ์ด๋ฏธ์ง€์˜ ๋†’์ด๋ฅผ ์ง€์ •ํ•ด์š” className="rounded-lg shadow-md" // Tailwind CSS ํด๋ž˜์Šค ์˜ˆ์‹œ /> </div> ); }

1๏ธโƒฃ ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€ ๊ตฌํ˜„

fill ์†์„ฑ๊ณผ sizes๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋ชจ ์ปจํ…Œ์ด๋„ˆ์— ๋งž์ถฐ ํฌ๊ธฐ๊ฐ€ ์กฐ์ ˆ๋˜๋Š” ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€๋ฅผ ๊ตฌํ˜„ํ•ด ๋ณผ๊ฒŒ์š”. ๋ถ€๋ชจ ์š”์†Œ๋Š” position: relative ๋˜๋Š” absolute, fixed, sticky ์†์„ฑ์„ ๊ฐ€์ ธ์•ผ ํ•ด์š”.

// components/ResponsiveHeroImage.tsx import Image from 'next/image'; import heroBanner from '@/public/hero-banner.jpg'; export default function ResponsiveHeroImage() { return ( <div style={{ width: '100%', height: '300px', // ๋ถ€๋ชจ ์š”์†Œ์˜ ๋†’์ด๋ฅผ ์ง€์ •ํ•˜์—ฌ ์ด๋ฏธ์ง€ ๊ณต๊ฐ„์„ ํ™•๋ณดํ•ด์š” position: 'relative', // fill ์†์„ฑ์„ ์œ„ํ•ด ํ•„์ˆ˜์˜ˆ์š” overflow: 'hidden' // ์ด๋ฏธ์ง€๊ฐ€ ๋ถ€๋ชจ๋ฅผ ๋ฒ—์–ด๋‚˜์ง€ ์•Š๋„๋ก ํ•ด์š” }}> <Image src={heroBanner} alt="๋ฐ˜์‘ํ˜• ์›น์‚ฌ์ดํŠธ ๋ฐฐ๋„ˆ" fill // ๋ถ€๋ชจ ์š”์†Œ์— ๊ฝ‰ ์ฑ„์šฐ๋„๋ก ํ•ด์š”. width, height๋Š” ํ•„์š” ์—†์–ด์š” sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" style={{ objectFit: 'cover' }} // ์ด๋ฏธ์ง€๊ฐ€ ๋ถ€๋ชจ ์š”์†Œ๋ฅผ ์ฑ„์šฐ๋„๋ก ํ•ด์š” priority={true} // LCP์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋†’์—ฌ์ค˜์š” placeholder="blur" /> </div> ); }

2๏ธโƒฃ LCP ์ด๋ฏธ์ง€ ์ตœ์ ํ™”

ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ ๊ฐ€์žฅ ๋จผ์ € ๋ณด์ด๋Š” ์ค‘์š”ํ•œ ์ด๋ฏธ์ง€์— priority ์†์„ฑ์„ ์‚ฌ์šฉํ•ด LCP๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ์˜ˆ์‹œ์˜ˆ์š”.

// pages/index.tsx ๋˜๋Š” app/page.tsx import Image from 'next/image'; import mainHero from '@/public/main-hero.jpg'; export default function HomePage() { return ( <main> <h1>๋ธ”๋ฃจ์˜ ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ด์š”!</h1> <Image src={mainHero} alt="๋ธ”๋กœ๊ทธ ๋ฉ”์ธ ํžˆ์–ด๋กœ ์ด๋ฏธ์ง€" width={1400} height={700} priority={true} // ์ด ์ด๋ฏธ์ง€๊ฐ€ LCP์— ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค๊ณ  ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ค˜์š” placeholder="blur" /> <section> {/* ... ๋‹ค๋ฅธ ์ฝ˜ํ…์ธ ๋“ค ... */} <p> ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ  ์ด์•ผ๊ธฐ๋ฅผ ํ•จ๊ป˜ ๋‚˜๋ˆ ๋ด์š”. </p> </section> </main> ); }

3๏ธโƒฃ ์™ธ๋ถ€ ์ด๋ฏธ์ง€ ๋„๋ฉ”์ธ ์„ค์ •

next.config.js์— ์™ธ๋ถ€ ์ด๋ฏธ์ง€ ๋„๋ฉ”์ธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ•์กฐํ• ๊ฒŒ์š”. ์ด ์„ค์ • ์—†์ด๋Š” ์™ธ๋ถ€ ์ด๋ฏธ์ง€๊ฐ€ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์•„์š”.

// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { images: { domains: ['images.unsplash.com', 'cdn.example.com'], // ์—ฌ๊ธฐ์— ์™ธ๋ถ€ ์ด๋ฏธ์ง€ ๋„๋ฉ”์ธ์„ ์ถ”๊ฐ€ํ•ด์š” // remotePatterns๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜๋„ ์žˆ์–ด์š” // remotePatterns: [ // { // protocol: 'https', // hostname: 'images.unsplash.com', // port: '', // pathname: '/**', // }, // ], }, }; module.exports = nextConfig;
์ •๋ณด

domains ์†์„ฑ๋ณด๋‹ค๋Š” remotePatterns๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•˜๊ณ  ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ด์—์š”. remotePatterns๋Š” ํŠน์ • ํ”„๋กœํ† ์ฝœ, ํ˜ธ์ŠคํŠธ๋„ค์ž„, ํฌํŠธ, ๊ฒฝ๋กœ๊นŒ์ง€ ์ง€์ •ํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋กœ๋”ฉ์„ ์—„๊ฒฉํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”.

๐Ÿ’ก Image ์ปดํฌ๋„ŒํŠธ ํ™œ์šฉ ํŒ๊ณผ ์ฃผ์˜์‚ฌํ•ญ

Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋”์šฑ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ๊ณผ ์ฃผ์˜์‚ฌํ•ญ์„ ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”.

0๏ธโƒฃ ํ˜„๋Œ€์ ์ธ ์ด๋ฏธ์ง€ ํฌ๋งท(WebP, AVIF) ํ™œ์šฉ

Next.js Image ์ปดํฌ๋„ŒํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ WebP๋‚˜ AVIF์™€ ๊ฐ™์€ ์ตœ์‹  ํฌ๋งท์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ œ๊ณตํ•ด์š”. ์ด ํฌ๋งท๋“ค์€ JPEG๋‚˜ PNG๋ณด๋‹ค ํ›จ์”ฌ ์ž‘์€ ํŒŒ์ผ ํฌ๊ธฐ๋กœ ๋” ๋‚˜์€ ํ’ˆ์งˆ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ, ๊ฐ€๋Šฅํ•œ ํ•œ ์›๋ณธ ์ด๋ฏธ์ง€๋ฅผ ๊ณ ํ’ˆ์งˆ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•Œ์•„์„œ ์ตœ์ ์˜ ํฌ๋งท์„ ์„ ํƒํ•ด ์ค„ ๊ฑฐ์˜ˆ์š”.

1๏ธโƒฃ alt ์†์„ฑ, ์ ˆ๋Œ€ ๋†“์น˜์ง€ ๋งˆ์„ธ์š”

alt ์†์„ฑ์€ ์‹œ๊ฐ ์žฅ์• ๊ฐ€ ์žˆ๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์›น ์ ‘๊ทผ์„ฑ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ๋Œ€์ฒด ํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ณ  SEO์—๋„ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ด์š”. ๋ชจ๋“  Image ์ปดํฌ๋„ŒํŠธ์— ์ด๋ฏธ์ง€์˜ ๋‚ด์šฉ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๋Š” alt ํ…์ŠคํŠธ๋ฅผ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•ด ์ฃผ์„ธ์š”.

2๏ธโƒฃ fill ๋ ˆ์ด์•„์›ƒ ์‚ฌ์šฉ ์‹œ ๋ถ€๋ชจ ์š”์†Œ ์Šคํƒ€์ผ๋ง

fill ์†์„ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ด๋ฏธ์ง€๊ฐ€ ๋ถ€๋ชจ ์š”์†Œ์— ๊ฝ‰ ์ฐจ๋„๋ก ๋ Œ๋”๋ง๋˜๋ฏ€๋กœ, ๋ถ€๋ชจ ์š”์†Œ์— position: relative (๋˜๋Š” absolute, fixed, sticky)์™€ ํ•จ๊ป˜ width, height๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”. ์ด๋ ‡๊ฒŒ ํ•ด์•ผ ์ด๋ฏธ์ง€๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ํฌ๊ธฐ์™€ ์œ„์น˜์— ๋ Œ๋”๋ง๋˜๊ณ , ๋ ˆ์ด์•„์›ƒ ์‰ฌํ”„ํŠธ๋„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

<div style={{ position: 'relative', // ํ•„์ˆ˜ width: '100%', height: '200px', // ๋ถ€๋ชจ ์š”์†Œ์˜ ๋†’์ด๋ฅผ ์ง€์ •ํ•ด์•ผ ์ด๋ฏธ์ง€๊ฐ€ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•ด์š” }}> <Image src="/my-image.jpg" alt="๊ฝ‰ ์ฑ„์›Œ์ง„ ์ด๋ฏธ์ง€" fill style={{ objectFit: 'cover' }} /> </div>

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์˜ค๋Š˜์€ Next.js Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์šฉํ•œ ์ด๋ฏธ์ง€ ์ตœ์ ํ™” ์ „๋žต์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ดค์–ด์š”. ๋‹จ์ˆœํžˆ <img> ํƒœ๊ทธ๋ฅผ <Image />๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ์ˆ˜๋งŽ์€ ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ์ •๋ง ๋†€๋ž์ง€ ์•Š๋‚˜์š”?

0๏ธโƒฃ ํ•ต์‹ฌ ์š”์•ฝ

  • Core Web Vitals ๊ฐœ์„ : Image ์ปดํฌ๋„ŒํŠธ๋Š” LCP, CLS ๋“ฑ ํ•ต์‹ฌ ์›น ์„ฑ๋Šฅ ์ง€ํ‘œ๋ฅผ ์ž๋™์œผ๋กœ ๊ฐœ์„ ํ•ด ์ค˜์š”.
  • ์ž๋™ ์ตœ์ ํ™”: ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€, ์ตœ์‹  ํฌ๋งท ๋ณ€ํ™˜, ๋ ˆ์ด์ง€ ๋กœ๋”ฉ ๋“ฑ ๋‹ค์–‘ํ•œ ์ตœ์ ํ™”๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณต๋ผ์š”.
  • ํ•„์ˆ˜ ์†์„ฑ: src, width, height, alt๋Š” ๋ฐ˜๋“œ์‹œ ์ง€์ •ํ•ด์•ผ ํ•ด์š”.
  • ๋ฐ˜์‘ํ˜•/LCP ์ตœ์ ํ™”: sizes ์†์„ฑ์œผ๋กœ ๋ฐ˜์‘ํ˜• ์ด๋ฏธ์ง€๋ฅผ, priority ์†์„ฑ์œผ๋กœ LCP ์ด๋ฏธ์ง€๋ฅผ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์™ธ๋ถ€ ์ด๋ฏธ์ง€: next.config.js์— domains ๋˜๋Š” remotePatterns ์„ค์ •์„ ์žŠ์ง€ ๋งˆ์„ธ์š”.

1๏ธโƒฃ ๋‹ค์Œ ์Šคํ…

์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์˜ Next.js ํ”„๋กœ์ ํŠธ์— Image ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์ ์šฉํ•ด ๋ณผ ์ฐจ๋ก€์˜ˆ์š”. ๊ธฐ์กด <img> ํƒœ๊ทธ๋“ค์„ <Image />๋กœ ๊ต์ฒดํ•˜๊ณ , priority, sizes, placeholder ๋“ฑ์˜ ์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์›น ํŽ˜์ด์ง€์˜ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•ด ๋ณด์„ธ์š”. ๊ตฌ๊ธ€ Lighthouse๋‚˜ PageSpeed Insights ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ์„  ํšจ๊ณผ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.

์„ฑ๋Šฅ ์ตœ์ ํ™”๋Š” ๋‹จ์ˆœํžˆ ๊ธฐ์ˆ ์ ์ธ ์ž‘์—…์„ ๋„˜์–ด, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋‚˜์€ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ์ค‘์š”ํ•œ ๊ณผ์ •์ด์—์š”. Next.js Image ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ์—ฌ๋Ÿฌ๋ถ„์˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋”์šฑ ๋น ๋ฅด๊ณ  ๋งค๋ ฅ์ ์œผ๋กœ ๋งŒ๋“ค์–ด๋‚˜๊ฐ€์‹œ๊ธธ ์‘์›ํ•ด์š”!

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ