๐Ÿฌ ๊ธดํ˜ธํก/๊ณ ์Šค๋ฝ ํ‹ฐ์ผ“

[๋‘๋‘ฅ] Next.js ์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”

ํ•œ๊ทœ์ง„ 2023. 7. 13. 16:03

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

 

์ดˆ๊ธฐ lightHouse ์ ์ˆ˜์ด๋‹ค. ๋‹คํ–‰ํžˆ ๋ง‰ ํฌ๊ฒŒ ์•ˆ์ข‹์€ ์ ์ˆ˜๋Š” ์•„๋‹ˆ์—ˆ๋‹ค.

 


 

1. ํฐํŠธ ์ตœ์ ํ™”

* ์›นํฐํŠธ๊ฐ€ ๋กœ๋“œ๋˜๋Š” ๋™์•ˆ ํ…์ŠคํŠธ๊ฐ€ ๊ณ„์† ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ

์›นํฐํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์—๋Š” ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. 

  • ๋Œ€์ฒด ๊ธ€๊ผด์ด ์ƒˆ ๊ธ€๊ผด๋กœ ๋ฐ”๋€œ (FOUT - ์Šคํƒ€์ผ์ด ์ง€์ •๋˜์ง€ ์•Š์€ ํ…์ŠคํŠธ ํ”Œ๋ž˜์‹œ).
  • "๋ณด์ด์ง€ ์•Š๋Š”" ํ…์ŠคํŠธ๋Š” ์ƒˆ ๊ธ€๊ผด์ด ๋ Œ๋”๋ง๋  ๋•Œ๊นŒ์ง€ ํ‘œ์‹œ๋จ (FOIT - ๋ณด์ด์ง€ ์•Š๋Š” ํ…์ŠคํŠธ ํ”Œ๋ž˜์‹œ).

 

ํ˜„์žฌ๋Š” ํฐํŠธ๊ฐ€ ๋ถˆ๋Ÿฌ์™€์ง€๊ธฐ ์ „๊นŒ์ง€๋Š” ์•„๋ฌด๋Ÿฐ ํ…์ŠคํŠธ๋„ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค๊ฐ€ ํฐํŠธ๊ฐ€ ๋กœ๋“œ๋œ ํ›„์— ํ…์ŠคํŠธ๊ฐ€ ๋™‡ ๋‚˜ํƒ€๋‚œ๋‹ค. ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ FOIT๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค (์‚ฌํŒŒ๋ฆฌ์—์„œ๋Š” ๊ถ์„œ์ฒด๋กœ ๋ณด์ด๋‹ค๊ฐ€ ๋ฐ”๋€Œ๋”๋ผ - FOUT ๋ฐฉ์‹) .

 

font-display :swap;

@font-face์˜ ์˜ต์…˜์„ ํ†ตํ•ด ๋ Œ๋”๋ง ๋ฐฉ์‹์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. swap์€ ๊ธ€์ž๋ฅผ ์ฐจ๋‹จํ•˜๋Š” ์‹œ๊ฐ„์„ ์ค„์ด๊ณ  ๊ธ€์ž๊ฐ€ ๋ถˆ๋Ÿฌ์™€์ง€๋ฉด ๊ต์ฒด(swap)ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. optional๊ณผ fallback ์˜ต์…˜์„ ํ†ตํ•ด, ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€๋งŒ ๊ธ€๊ผด ์ฐจ๋‹จ ๊ธฐ๊ฐ„ ๋˜๋Š” swap์„ ๋Œ€๊ธฐํ•˜๋Š” (๊ธ€๊ผด ๊ต์ฒด) ๊ธฐ๊ฐ„์„ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๊ธ€๊ผด ๋กœ๋“œ ์ค‘ ๋ณด์ด์ง€ ์•Š๋Š” ํ…์ŠคํŠธ ๋ฐฉ์ง€

๊ธ€๊ผด์€ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ผ๋ถ€ ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ธ€๊ผด์ด ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ํ…์ŠคํŠธ๋ฅผ ์ˆจ๊น๋‹ˆ๋‹ค("๋ณด์ด์ง€ ์•Š๋Š” ํ…์ŠคํŠธ์˜ ๊นœ๋ฐ•์ž„(FOIT)". ์„ฑ๋Šฅ์„

web.dev

 

* ์›นํฐํŠธ ๋ฏธ๋ฆฌ ๋กœ๋“œ

FOUT๋ฅผ ๋ฐฉ์ง€ ํ•˜๊ธฐ ์œ„ํ•ด ์ฆ‰์‹œ ํ•„์š”ํ•œ ์›นํฐํŠธ๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค. html head์— ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ Link ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

<head>
  <!-- ... -->
  <link
    rel="preload"
    as="style"
    crossOrigin="anonymous"
    href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.6/dist/web/static/pretendard.css"
  />
</head>

preload๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ• ๋•Œ์— ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‹น๊ฒจ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์‹ค์ œ๋กœ ์ ์šฉํ•œ ํ›„์— ์ƒˆ๋กœ ๋นŒ๋“œํ•ด ํ™•์ธํ•ด๋ณด๋‹ˆ ๊ธ€๊ผด์ด ๊นœ๋นก์ด๋Š” ํ˜„์ƒ์ด ์‚ฌ๋ผ์ง„๊ฒƒ์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

ํฌ๋กฌ๋งŒ ์ƒ๊ฐํ–ˆ์—ˆ์ง€..

ํ•˜์ง€๋งŒ Safari (๋˜๋Š” ๋ชจ๋ฐ”์ผ ๋ธŒ๋ผ์šฐ์ €)์—์„œ๋Š” ์ ์šฉ์ด ๋˜์ง€ ์•Š์•˜๋‹ค. ์ฃ„๋‹ค ๊ธฐ๋ณธ ๊ธ€๊ผด๋กœ ๊นจ์ ธ์„œ ๋‚˜ํƒ€๋‚ฌ๋‹ค. ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์—๋„ ๋น„์Šทํ•œ ์งˆ๋ฌธ๋“ค์ด ๋งŽ์•˜์Œ.

 

<head>
  <!-- ... -->
  <link
    rel="preload"
    as="style"
    href="https://asset.dudoong.com/common/fonts/dudoong-fonts.css"
    crossOrigin="anonymous"
  />
</head>

๋‘๋‘ฅ ์›น์˜ Origin๊ณผ ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์›นํฐํŠธ CDN์˜ Origin์ด ๋‹ฌ๋ผ์„œ cross-origin ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. @font-face cssํŒŒ์ผ์„ ๋‘๋‘ฅ ์ธํ”„๋ผ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” CDN์— ๋„์›Œ์„œ ์ง์ ‘ ์ œ๊ณตํ•ด๋ณด๋ ค๊ณ  ํ–ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๊ฒฐ๊ณผ๋Š” ๋˜‘๊ฐ™์•˜๋‹ค.

 

https://www.w3.org/TR/css-fonts-3/#font-fetching-requirements

๊ธ€๊ผด์„ ์š”์ฒญํ• ๋•Œ๋Š” CORS์š”์ฒญ์œผ๋กœ ์ „์†ก๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๋„๋ฉ”์ธ์ด ๋‹ค๋ฅผ๋• ์š”์ฒญ์ด ๋˜์ง€ ์•Š๋˜๊ฒƒ์ด์—ˆ๋Š”๋ฐ, ์„œ๋ธŒ ๋„๋ฉ”์ธ๋„ ๋˜‘๊ฐ™์ด cross-origin์œผ๋กœ ๋ถ„๋ฅ˜๋˜๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. CDN ์„ค์ •์—์„œ Allow-Origin์„ ๋ชจ๋‘ ์—ด์–ด์ฃผ์—ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ œ๋Œ€๋กœ ์š”์ฒญ์ด ๋˜์ง€ ์•Š์•˜๋‹ค. ์ด ๊ธ€์„ ๋ณด๋ฉด ๋ชจ์ข…์˜ ์ด์œ ๋กœ safari์—์„œ cdn์— ๋Œ€ํ•œ preload ์š”์ฒญ์ด ์•ˆ๋˜๋Š”๊ฒƒ์œผ๋กœ ๋ณด์˜€๋‹ค.

 

* ์›นํฐํŠธ ํฌ๊ธฐ ์ค„์ด๊ธฐ

๋ญ ์ด๋Ÿฐ๊ฒƒ๋“ค์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

  • WOFF2์™€ ๊ฐ™์€ ์šฉ๋Ÿ‰์ด ์ž‘์€ ์••์ถ•๋œ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๊ธฐ
  • @font-face๋ฅผ ํ†ตํ•ด ๊ธ€๊ผด ๋ชจ์Œ์„ ์ •์˜ํ•˜๊ธฐ
  • ์„œ๋ธŒ์…‹, ๋‹ค์ด๋‚˜๋ฏน ์„œ๋ธŒ์…‹ ๋“ฑ์„ ํ†ตํ•ด ๊ธ€๊ผด์˜ ์šฉ๋Ÿ‰์„ ์ค„์ด๊ธฐ

1๋ฒˆ๊ณผ 2๋ฒˆ๊ฐ™์€ ๊ฒฝ์šฐ์—” ์ด๋ฏธ ์ ์šฉ์ด ๋˜์–ด ์žˆ์—ˆ๊ณ , 3๋ฒˆ์„ ํ†ตํ•ด ์›นํฐํŠธ ๋ฆฌ์†Œ์Šค์˜ ์šฉ๋Ÿ‰์„ ์ค„์—ฌ๋ณด์•˜๋‹ค.

 

https://www.44bits.io/ko/post/optimization_webfont_with_pyftsubnet

์„œ๋ธŒ์…‹ ํฐํŠธ๋Š” ํฐํŠธ ํŒŒ์ผ์—์„œ ๋ถˆํ•„์š”ํ•œ ๊ธ€์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์‚ฌ์šฉํ•  ๊ธ€์ž๋งŒ ๋‚จ๊ฒจ๋‘” ํฐํŠธ๋‹ค. ๋ณดํ†ต์€ '๋ท'๊ณผ ๊ฐ™์€ ๊ธ€์ž๋Š” ์“ฐ์ง€ ์•Š์œผ๋‹ˆ๊นŒ. 26๊ฐœ์˜ ์•ŒํŒŒ๋ฒณ๊ณผ ๋‹ฌ๋ฆฌ ํ•œ๊ธ€ ์กฐํ•ฉ์€ ๋งŒ๊ฐœ ์–ธ์ €๋ฆฌ๋‚˜ ๋˜๋Š”๋ฐ, ์„œ๋ธŒ์…‹ ํฐํŠธ๋กœ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋ฉด 2300๊ฐœ ์ •๋„์˜ ๊ธ€์ž๋งŒ ๋‚จ๊ฒจ๋‘˜ ์ˆ˜ ์žˆ๋‹ค. ๋•๋ถ„์— ์šฉ๋Ÿ‰์ด ํ›จ์‹  ์ž‘์•„์ง„๋‹ค. ์„œ๋ธŒ์…‹ ํฐํŠธ ๋ฉ”์ด์ปค๋ผ๋Š” ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทผ๋ฐ ์›น์—์„œ ์“ฐ์ด๋Š” ์›ฌ๋งŒํ•œ ํฐํŠธ๋Š” ์ด๋ฏธ ์žˆ๋Š”๋“ฏ.

 

ํ•˜์ง€๋งŒ ๊ทธ๋ž˜๋„ ์—ฌ์ „ํžˆ ๋งŽ๋‹ค. ๊ทธ ์ค‘์—์„œ๋„ ์•ˆ์“ฐ๋Š” ํฐํŠธ๊ฐ€ ์ •๋ง ๋งŽ์€๋ฐ. ๋‹ค์ด๋‚˜๋ฏน ์„œ๋ธŒ์…‹์€ CSS์˜ unicode-range ์†์„ฑ์„ ํ†ตํ•ด, ํ•ด๋‹น ์œ ๋‹ˆ์ฝ”๋“œ ์˜์—ญ์˜ ๋ฌธ์ž๊ฐ€ ์‚ฌ์šฉ๋  ๋•Œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํฐํŠธ ํŒŒ์ผ๋ฅผ ์š”์ฒญํ•œ๋‹ค.

 

/* [0] */
@font-face {
    font-family: 'Pretendard';
    font-style: normal;
    font-display: swap;
    font-weight: 100;
    src: url(../../../packages/pretendard/dist/web/static/woff2-dynamic-subset/Pretendard-Thin.subset.0.woff2) format('woff2'), url(../../../packages/pretendard/dist/web/static/woff-dynamic-subset/Pretendard-Thin.subset.0.woff) format('woff');
    unicode-range: U+f9ca-fa0b, U+ff03-ff05, U+ff07, U+ff0a-ff0b, U+ff0d-ff19, U+ff1b, U+ff1d, U+ff20-ff5b, U+ff5d, U+ffe0-ffe3, U+ffe5-ffe6;
}
/* [1] */
@font-face {
    font-family: 'Pretendard';
    font-style: normal;
    font-display: swap;
    font-weight: 100;
    src: url(../../../packages/pretendard/dist/web/static/woff2-dynamic-subset/Pretendard-Thin.subset.1.woff2) format('woff2'), url(../../../packages/pretendard/dist/web/static/woff-dynamic-subset/Pretendard-Thin.subset.1.woff) format('woff');
    unicode-range: U+d723-d728, U+d72a-d733, U+d735-d748, U+d74a-d74f, U+d752-d753, U+d755-d757, U+d75a-d75f, U+d762-d764, U+d766-d768, U+d76a-d76b, U+d76d-d76f, U+d771-d787, U+d789-d78b, U+d78d-d78f, U+d791-d797, U+d79a, U+d79c, U+d79e-d7a3, U+f900-f909, U+f90b-f92e;
}
/* https://github.com/orioncactus/pretendard */

์‹ค์ œ ํ”„๋ฆฌํ…๋‹ค๋“œ ๋‹ค์ด๋‚˜๋ฏน ์„œ๋ธŒ์…‹ ํฐํŠธ ํŒŒ์ผ์˜ ๋‚ด์šฉ์ด๋‹ค. ํ•œ๊ธ€์€ ๋งค์šฐ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž๋“ค ์กฐ๊ธˆ๊ณผ, ๋น„๊ต์  ์ ๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ž๋“ค ๋‹ค์ˆ˜๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทธ๊ฑธ ๊ตฌ๊ธ€๊ป˜์„œ ์–ด์ฉŒ๊ตฌ์ €์ฉŒ๊ตฌ ํ•ด์„œ ์ตœ์ ์˜ unicode-range๋กœ ๋‚˜๋ˆ„์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค. https://www.googblogs.com/tag/korean/

 

๊ฐ€๋ฒผ์šด ํ”„๋ฆฌํ…๋‹ค๋“œ์™€ 0.6๋ฉ”๊ฐ€ ์ง€๋งˆ์ผ“์‚ฐ์ฆˆ

๋ณดํ†ต Header์˜ ํฐํŠธ๋กœ ์‚ฌ์šฉํ•˜๋Š” Gmarket Sans๋ฅผ ๋‹ค์ด๋‚˜๋ฏน ์„œ๋ธŒ์…‹ ํŒŒ์ผ๋กœ ๋ณ€๊ฒฝ๋งŒ ํ•ด๋„ ๊ธฐ์กด 1.3mb์—์„œ 408kb๊นŒ์ง€ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํ”„๋ฆฌํ…๋‹ค๋“œ๋Š” @font-face์˜ src์—์„œ local์„ ํ†ตํ•ด ๋กœ์ปฌ ํฐํŠธํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋˜์–ด์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ธฐ์กด ์šฉ๋Ÿ‰์ด ์–ผ๋งˆ๋‚˜ ๋˜๋Š”์ง€ ๋”ฐ๋กœ ์•Œ์•„๋ณด๊ธด ๊ท€์ฐฎ์•„์„œ ํŒจ์Šค. ๋Œ€๋ถ€๋ถ„ ์•„์ดํฐ์— ํ”„๋ฆฌํ…๋‹ค๋“œ๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ์„ ์ผ์€ ๋ณ„๋กœ ์—†๋‹ค๋ณด๋‹ˆ ํ”„๋ฆฌํ…๋‹ค๋“œ ์—ญ์‹œ ๋‹ค์ด๋‚˜๋ฏน ์„œ๋ธŒ์…‹ ํฐํŠธ๋กœ ๋ฐ”๊พธ์–ด ์ฃผ์—ˆ๋‹ค.

 

์ฒ˜์Œ๋ถ€ํ„ฐ next/font๋ฅผ ์ ์šฉํ•ด๋ณผ๊ฑธ ํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ์ฒ˜์Œ์—” ๊ตฌ๊ธ€ํฐํŠธ๊ฐ€ ์•„๋‹Œ ์›นํฐํŠธ๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์•˜๋‹ค. ๊ทผ๋ฐ ๋กœ์ปฌ๋กœ ๋‹ค์šด๋ฐ›์•„์„œ ์„œ๋ธŒ์…‹ ํฐํŠธ ๋งŒ๋“ค๊ณ , ๋‚ด CDN์— ์˜ฌ๋ฆฌ๊ณ  ๋“ฑ์˜ ์—ฌ๋Ÿฌ ์‹œ๋„๋ฅผ ํ•˜๋ฉด์„œ.. ์ด๋Ÿด๋ฐ”์—” ๊ทธ๋ƒฅ ๋กœ์ปฌํฐํŠธ๋กœ next/font๋ฅผ ์ ์šฉํ•˜๋Š”๊ฒŒ ๋งž์ง€ ์•Š๋‚˜? ํ•˜๋Š” ์ƒ๊ฐ.

 

 

2. ์ด๋ฏธ์ง€ ์ตœ์ ํ™”

ํฐํŠธ๋ณด๋‹ค ๋” ํฐ ๋ฌธ์ œ๋Š” ์ด๋ฏธ์ง€์— ์žˆ์—ˆ๋‹ค. ๋‘๋‘ฅ์˜ ๋ฉ”์ธํŽ˜์ด์ง€๋Š” ํ˜ธ์ŠคํŠธ๊ฐ€ ์˜ฌ๋ฆฐ ํฌ์Šคํ„ฐ ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋Œ€๋กœ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์—ˆ๋‹ค. ์šฉ๋Ÿ‰์ด ๋งค์šฐ ๋งŽ์€ ์ด๋ฏธ์ง€๋กœ ์—…๋กœ๋“œํ•ด๋†“์œผ๋ฉด ๊ทธ๋Ÿฐ๋Œ€๋กœ ๋กœ๋”ฉ์ด ๋Š๋ ค์ง€๋Š” ์ƒํ™ฉ์ด์—ˆ์Œ.

 

๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด์„œ ์ด๋Ÿฐ ๊ฒƒ๋“ค์„ ํ•œ๋‹ค.

  • ์ด๋ฏธ์ง€ ์‚ฌ์ด์ฆˆ๋ฅผ ๋ณด์—ฌ์ค„ ํฌ๊ธฐ ๋˜๋Š” ๋ทฐํฌํŠธ์— ๋งž๊ฒŒ ๋ณ€ํ™˜ํ•ด์„œ ์ œ๊ณตํ•œ๋‹ค.
  • ์šฉ๋Ÿ‰์ด ์ž‘๊ฒŒ ์••์ถ•๋œ ํŒŒ์ผ ํ™•์žฅ์ž(WEBP)๋ฅผ ์ด์šฉํ•œ๋‹ค.
  • ์ฒ˜์Œ์— ๋ชจ๋“  ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜์ง€ ์•Š๊ณ , ๋ทฐํฌํŠธ์— ๋ณด์—ฌ์งˆ ๊ฒƒ๋“ค๋งŒ lazy loading ํ•œ๋‹ค.
  • ์ด๋ฏธ์ง€์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์ง€์ •ํ•ด Cumulative Layout Shift๋ฅผ ๋ฐฉ์ง€ํ•œ๋‹ค.

 

์ด๋ฅผ ์œ„ํ•ด Next/Image๋ฅผ ๋„์ž…ํ–ˆ๋‹ค. ์œ„์˜ ๊ฒƒ๋“ค์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„  intersection-observer ๋“ฑ์„ ํ†ตํ•ด ์ง์ ‘ ๋ทฐํฌํŠธ์— ๋ณด์ด๋Š”์ง€๋ฅผ ์บ์น˜ํ•ด lazy loading์„ ์ ์šฉํ•ด์•ผ ํ•˜๊ณ (ํฌ๋กฌ์€ ๋œ๋Œ€), ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•  ๋•Œ ๋ณ„๋„์˜ ์ด๋ฏธ์ง€ ์••์ถ• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ฆฌ์‚ฌ์ด์ง•๊ณผ ์••์ถ•์„ ํ•œ ํ›„์— ์Šคํ† ๋ฆฌ์ง€์— ์—…๋กœ๋“œํ•˜๋Š” ๋ฐฉ์‹์ด ํ•„์š”ํ•˜๋‹ค.

๋‚ด๊ฐ€ ๋ชจ๋ฅด๋Š”๊ฑฐ ์žˆ์œผ๋ฉด ๋ง์ข€

 

๊ทผ๋ฐ Next/Image๋Š” ์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์„ ๋‹ค ์ œ๊ณตํ•ด์ค€๋‹ค.

 

<Image
  src={img}
  fill={true}
  sizes="(max-width: 768px) 50vw, 25vw"
  alt={props.name}
  priority
/>

ํ˜„์žฌ ๋ฉ”์ธ ํŽ˜์ด์ง€์— ์ ์šฉ๋œ Image ์ปดํฌ๋„ŒํŠธ์ด๋‹ค. ์ธํ„ฐ๋„ท์— ๋งŽ์ด ์žˆ๋Š” ์ž๋ฃŒ๋“ค์€ ๋ ˆ๊ฑฐ์‹œ์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์„œ, ๊ณต์‹๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค.

 

* fill

๋ ˆ์ด์•„์›ƒ ์‹œํ”„ํŠธ๋ฅผ ์—†์• ๊ธฐ ์œ„ํ•ด width์™€ height๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค ํ–ˆ๋Š”๋ฐ, ๋Œ€์‹  fill ์†์„ฑ์„ ์‚ฌ์šฉํ–ˆ๋‹ค. fill์„ ํ†ตํ•ด ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์œ„ ์š”์†Œ๋ฅผ ์ฑ„์šฐ๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

position: relative;
padding-top: 141.4%;
overflow: hidden;

Image ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ์œ„ ์š”์†Œ์—๋Š” ์œ„์™€ ๊ฐ™์ด relative์™€ overflow: hidden ์†์„ฑ์„ ์ฃผ๊ณ , 141.4%(A์‚ฌ์ด์ฆˆ ์šฉ์ง€)์˜ ๋น„์œจ๋กœ ์œ ์ง€๋˜๋„๋ก ํ–ˆ๋‹ค.

 

* sizes

์ด๋ฏธ์ง€๊ฐ€ ๋ฐ˜์‘ํ˜•์ผ๋•Œ next-images๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๋ฅผ 100vw๋กœ ์ƒ๊ฐํ•˜๊ณ  ๋‚ด๋ ค์ค€๋‹ค. sizes ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹ค์ œ ์ด๋ฏธ์ง€์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ 100vw๋ณด๋‹ค ์ž‘์„๊ฑฐ๋ผ๊ณ  ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์•Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋ฐ”์ผ ํ™”๋ฉด์ผ๋• 1์—ด์— ํฌ์Šคํ„ฐ๊ฐ€ ๋‘๊ฐœ, ์•„๋‹ ๋• ๋„ค๊ฐœ์”ฉ ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— (max-width: 768px) 50vw, 25vw๋กœ ์„ค์ •ํ•ด์ฃผ์—ˆ๋‹ค. sizes์†์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„๋•Œ๋ณด๋‹ค 16๋ฐฐ ์ž‘์€ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

์ถ”๊ฐ€๋กœ ์ด๋ฏธ์ง€์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋†’์ด๊ณ  preloadํ•˜๊ธฐ ์œ„ํ•ด priority ์†์„ฑ์„ ์ค„ ์ˆ˜ ์žˆ๊ณ , ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋”ฉ๋˜๊ธฐ๊นŒ์ง€ ๋ณด์—ฌ์ค„ placeholder ๋˜๋Š” blur ์ด๋ฏธ์ง€๋ฅผ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์Šคํฌ๋กค ์—†์ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ด๋ฏธ์ง€๊ฐ€ ์ง€์—ฐ ๋กœ๋“œ๋˜๋ฉด ํŽ˜์ด์ง€ ์ˆ˜๋ช… ์ฃผ๊ธฐ ํ›„๋ฐ˜์— ๋ Œ๋”๋ง๋˜๋ฏ€๋กœ preload ์†์„ฑ์„ ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์ด๋ ‡๊ฒŒ Next/Image ์ปดํฌ๋„ŒํŠธ๋กœ ๋Œ€์ฒดํ•˜๋ฉด์„œ ๋‘๋‘ฅ ๋ฉ”์ธ ํŽ˜์ด์ง€์˜ ์ดˆ๊ธฐ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ 1800kb์—์„œ 444kb๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋ฏธ์ง€๋งŒ์œผ๋กœ๋„ ํ™•์‹คํžˆ ๋กœ๋”ฉ ์†๋„๊ฐ€ ๋นจ๋ผ์ง์„ ์ฒด๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ œ์ผ ๋Œ€๋ฌธ์ง๋งŒํ•˜๊ธด ํ•ด์„œ.

 

 

3. ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ ์ตœ์ ํ™”

๋ณดํŽธ์ ์œผ๋กœ ์‰ฝ๊ฒŒ ๋ฒˆ๋“ค์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์ด ์žˆ๋‹ค. Next๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ pages๋‚ด์˜ ํŒŒ์ผ๋“ค์„ ๋นŒ๋“œ ๊ณผ์ •์—์„œ ๋ถ„ํ• ํ•ด ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์„ ์ž๋™์ ์œผ๋กœ ์ง€์›ํ•ด์ค€๋‹ค. ๊ทธ ์™ธ์— ๋ฐ”๋กœ ๊ฐ€์ ธ์˜ฌ ํ•„์š”๊ฐ€ ์—†๋Š” ์ฝ”๋“œ๋“ค์€ dynamic import๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ๋•Œ์— ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

๋‘๋‘ฅ์˜ ๊ฒฝ์šฐ์—” ๋ชจ๋‹ฌ(ํ˜น์€ ๋ฐ”ํ…€์‹œํŠธ)๋ฅผ ๊ธ€๋กœ๋ฒŒ๋กœ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด, ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— ์œ„์น˜ํ•ด๋†“๊ณ  ์ „์—ญ์ƒํƒœ๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค. ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค.

 

const GlobalOverlay = dynamic(
  () => import('@components/shared/overlay/GlobalOverlay'),
  { ssr: false },
);

์ด ์™ธ์—๋„ MdViewer, QRcode ๋“ฑ์˜ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ next/dynamic์„ ํ†ตํ•ด ๋™์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์žˆ๋‹ค.

 

์‚ฌ์šฉ๋œ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ๋งŽ์€ ์šฉ๋Ÿ‰์„ ์ฐจ์ง€ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ฆฌ์…ฐ์ดํ‚น์„ ํ•˜๊ณค ํ•œ๋‹ค. next/bundle-analyzer๋ฅผ ํ†ตํ•ด Next ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•  ๋•Œ ์–ด๋–ค ๋ชจ๋“ˆ์ด ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์šฉ๋Ÿ‰์„ ์ฐจ์ง€ํ•˜๋Š”์ง€ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

https://www.npmjs.com/package/@next/bundle-analyzer

 

์‚ฌ์‹ค ํฌ๊ฒŒ ๋ˆˆ์— ๋„๋Š” ๋ถ€๋ถ„์€ ์—†๋‹ค. ๋‹ค๋งŒ ๋””์ž์ด๋„ˆ๊ฐ€ ๋žœ๋”ฉํŽ˜์ด์ง€์˜ ์ผ๋Ÿฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค์–ด์ค€ ์ด๋ฏธ์ง€๋“ค์„ ๊ทธ๋Œ€๋กœ svg๋กœ ๋„ฃ์—ˆ๋Š”๋ฐ, ์ง€๊ธˆ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๋ฏธ์นœ ์ง“์ด์—ˆ์Œ. ์–ด์ฐจํ”ผ ๋žœ๋”ฉํŽ˜์ด์ง€ ๋ฆฌ๋‰ด์–ผ ์ž‘์—…์ค‘์ด๋ผ ๋‚˜์ค‘์— ์‹น ๋ฐ”๊ฟ€ ์˜ˆ์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง€๊ธˆ ๋‹น์žฅ์€ ๊ฑด๋“ค ์ƒ๊ฐ์ด ์—†๋‹ค. ํŽ˜์ด์ง€ ๋งจ ์œ„ ์„น์…˜ ์™ธ์˜ ์•„๋ž˜ ๋‚˜์˜ค๋Š” ์„น์…˜๋“ค์€ ๋‹ค์ด๋‚˜๋ฏน ์ž„ํฌํŠธ๋ฅผ ํ†ตํ•ด ๋ ˆ์ด์ง€ํ•˜๊ฒŒ ๋กœ๋”ฉ๋˜๋„๋ก ์ˆ˜์ •ํ•ด์ฃผ์—ˆ๋‹ค.

 

์ˆ˜์ • ์ „ํ›„ pages/index.js ๋ชจ๋“ˆ์˜ analyzer ๊ฒฐ๊ณผ์ด๋‹ค. ๋นŒ๋“œ ํŒŒ์ผ์— ๋ฌด๊ฑฐ์šด svg๋“ค์ด ์ œ๊ฑฐ๋œ๊ฒƒ์„ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

์ „ / ํ›„

์ตœ์ ํ™” ์ž‘์—… ์ „ ํ›„๋กœ ๋นŒ๋“œ๋œ JSํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ๋ˆˆ์— ๋ณด์ด๊ฒŒ ์ค„์–ด๋“ค์—ˆ๋‹ค.

 


 

๋ฉ”์ธ ํŽ˜์ด์ง€๋Š” 89์ , ๊ณต์—ฐ ์ƒ์„ธํŽ˜์ด์ง€๋Š” 98์ ๊นŒ์ง€ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค. ์•„๋งž๋‹ค ์ ‘๊ทผ์„ฑ.