09. ๐Ÿš€ ์›น ์„ฑ๋Šฅ ์ตœ์ ํ™”์™€ Core Web Vitals

2026๋…„ 4์›” 30์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

Core Web Vitals์˜ ํ•ต์‹ฌ ์ง€ํ‘œ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์ฝ”๋“œ ๋ถ„ํ• (Code Splitting)๋ถ€ํ„ฐ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”๊นŒ์ง€ ์‹ค์ „ ์„ฑ๋Šฅ ๊ฐœ์„  ๊ธฐ์ˆ ์„ ์ •๋ณตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ด ๋ฉด์ ‘ ํ•ญ๋ชฉ์˜ ๋ชฉํ‘œ

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 25๋ถ„ (ํ•ต์‹ฌ ์š”์•ฝ: 12๋ถ„)

๐Ÿ—บ๏ธ ์ด ์ฑ•ํ„ฐ์˜ ํ๋ฆ„
[๊ฐœ๋… ์‚ฌ์ „] โ†’ [์งˆ๋ฌธ 1: Core Web Vitals (LCP/CLS)] โ†’ [์งˆ๋ฌธ 2: ์ฝ”๋“œ ๋ถ„ํ•  & ๋ฒˆ๋“ค ์ตœ์ ํ™”] โ†’ [์‹ค์ „ ๋ณ€ํ˜• ์งˆ๋ฌธ]

๐ŸŽฏ ์ด ์ฑ•ํ„ฐ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • LCP, CLS ๋“ฑ ํ•ต์‹ฌ ์„ฑ๋Šฅ ์ง€ํ‘œ์˜ ์˜๋ฏธ์™€ ๊ตฌ์ฒด์ ์ธ ๊ฐœ์„  ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • Dynamic Import๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„๋ฅผ ํš๊ธฐ์ ์œผ๋กœ ์ค„์ด๋Š” ์ „๋žต์„ ์„ธ์›๋‹ˆ๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ(CRP)๊ณผ ์—ฐ๊ณ„๋œ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ์ง€์ ์„ ์ง„๋‹จํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“š ํ•ต์‹ฌ ๊ฐœ๋… ์‚ฌ์ „ (Concept Glossary)

1. LCP (Largest Contentful Paint)

ํŽ˜์ด์ง€์˜ ์ฃผ์š” ์ฝ˜ํ…์ธ (๊ฐ€์žฅ ํฐ ์ด๋ฏธ์ง€๋‚˜ ํ…์ŠคํŠธ ๋ธ”๋ก)๊ฐ€ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ 'ํŽ˜์ด์ง€๊ฐ€ ์‹ค์ œ๋กœ ๋กœ๋”ฉ๋˜์—ˆ๋‹ค'๊ณ  ๋А๋ผ๊ฒŒ ํ•˜๋Š” ๊ฒฐ์ •์ ์ธ ์ง€ํ‘œ์ž…๋‹ˆ๋‹ค.

2. CLS (Cumulative Layout Shift)

๋กœ๋”ฉ ๋„์ค‘ ์˜ˆ์ƒ์น˜ ์•Š๊ฒŒ ๋ ˆ์ด์•„์›ƒ์ด ์›€์ง์ด๋Š” ์ •๋„๋ฅผ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ ค๋Š”๋ฐ ๊ฐ‘์ž๊ธฐ ์ด๋ฏธ์ง€๊ฐ€ ๋œจ๋ฉด์„œ ๋ฒ„ํŠผ์ด ์•„๋ž˜๋กœ ๋ฐ€๋ฆฌ๋Š” ๋“ฑ์˜ ๋ถˆ์พŒํ•œ ๊ฒฝํ—˜์„ ์ˆ˜์น˜ํ™”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

3. ์ฝ”๋“œ ๋ถ„ํ•  (Code Splitting)

ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋‹น์žฅ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ๋Š” ๋‚˜์ค‘์— ๋กœ๋”ฉํ•˜์—ฌ ์ดˆ๊ธฐ ๊ตฌ๋™ ์†๋„๋ฅผ ๋†’์ž…๋‹ˆ๋‹ค.


๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  (ํ›„๋ฐ˜): "์˜ํ˜ธ ๋‹˜! '์˜์ˆ˜๋„ค ๋ฉ”์ธ ํŽ˜์ด์ง€' ๋ผ์ดํŠธํ•˜์šฐ์Šค(Lighthouse) ์ ์ˆ˜๊ฐ€ ๋นจ๊ฐ„์ƒ‰์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ด๋ฏธ์ง€๊ฐ€ ๋Šฆ๊ฒŒ ๋– ์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ฒซ ํ™”๋ฉด์„ ๋ถˆ์•ˆํ•˜๊ฒŒ ๋ณผ ๊ฒƒ ๊ฐ™์•„์š”."
  • ๐Ÿฆ ์˜ํ˜ธ (๋ฆฌ๋“œ): "์˜์ฒ  ๋‹˜, ์ ์ˆ˜ ์ž์ฒด๋ณด๋‹ค ์ค‘์š”ํ•œ ๊ฑด ์‚ฌ์šฉ์ž์˜ ์ฒด๊ฐ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๊ฐ€ ๋Šฆ๊ฒŒ ๋œจ๋Š” ๊ฑด ์†Œ์Šค๊ฐ€ ๋ฌด๊ฑฐ์›Œ์„œ์ผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด๋ฏธ์ง€์˜ ์ž๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๋ชฐ๋ผ์„œ ๋ ˆ์ด์•„์›ƒ์ด ์›€์ง์ด๊ธฐ ๋•Œ๋ฌธ์ผ ์ˆ˜๋„ ์žˆ์ฃ . ์ง€ํ‘œ์™€ ์‚ฌ์šฉ์ž ํ๋ฆ„์„ ํ•จ๊ป˜ ๋ด…์‹œ๋‹ค."

๋ฉด์ ‘ ์งˆ๋ฌธ 1. Core Web Vitals ์ค‘ LCP์™€ CLS ์ง€ํ‘œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์ฒด์ ์ธ ์ „๋žต์„ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.

๐ŸŽฏ ์ถœ์ œ ์˜๋„

ํ˜„๋Œ€์ ์ธ ์›น ์„ฑ๋Šฅ ์ง€ํ‘œ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ๋‹จ์ˆœํžˆ ์•„๋Š” ๊ฒƒ์„ ๋„˜์–ด ์‹ค์ œ ์ฝ”๋“œ๋กœ ์–ด๋–ป๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€(์˜ˆ: ์ด๋ฏธ์ง€ ํƒœ๊ทธ ์†์„ฑ, ํฐํŠธ ๋กœ๋”ฉ ๋“ฑ) ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ Naive ๊ตฌํ˜„ (Bad Case)

์˜์ฒ ์ด๋Š” ์ด๋ฏธ์ง€ ํƒœ๊ทธ์— ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ , ๋ชจ๋“  ์ด๋ฏธ์ง€๋ฅผ ํ•œ ๋ฒˆ์— ๋กœ๋”ฉํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.

<!-- ๐Ÿฃ ์˜์ฒ : "์ด๋ฏธ์ง€๊ฐ€ ์•Œ์•„์„œ ํฌ๊ธฐ์— ๋งž์ถฐ ๋‚˜์˜ค๊ฒ ์ฃ ?" -->
<img src="/hero-banner.jpg" alt="๋ฉ”์ธ ๋ฐฐ๋„ˆ">
<!-- โš ๏ธ ๋ฌธ์ œ:
   1. ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ์ „ ํฌ๊ธฐ๋ฅผ ๋ชฐ๋ผ CLS ๋ฐœ์ƒ (๋ ˆ์ด์•„์›ƒ ํ”๋“ค๋ฆผ)
   2. ์ตœ์ ํ™”๋˜์ง€ ์•Š์€ ํฐ ์šฉ๋Ÿ‰์œผ๋กœ ์ธํ•ด LCP ์ง€์—ฐ
-->

๐Ÿฆ ์˜ํ˜ธ์˜ ๋ฆฌ๋ทฐ ํฌ์ธํŠธ
"์˜์ฒ  ๋‹˜, ๋ธŒ๋ผ์šฐ์ €๋Š” ์˜ˆ์–ธ์ž๊ฐ€ ์•„๋‹ˆ์—์š”. ์ด๋ฏธ์ง€ ์ž๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ์žก์•„์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์งˆ ๋•Œ๋งˆ๋‹ค ์ „์ฒด ํ™”๋ฉด์ด ๋„๋›ฐ๊ธฐ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ธ ์ด๋ฏธ์ง€๋Š” '๊ฐ€์žฅ ๋†’์€ ์šฐ์„ ์ˆœ์œ„'๋กœ ๋ฐ›์•„์•ผ์ฃ ."

๐Ÿฆ ์˜ํ˜ธ์˜ ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ (Good Case)

์˜ํ˜ธ ๋ฆฌ๋“œ๊ฐ€ ์ œ์•ˆํ•˜๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ์ •์„์ž…๋‹ˆ๋‹ค.

<!-- ๐Ÿฆ ์˜ํ˜ธ: "๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ํฌ๊ธฐ, ์šฐ์„ ์ˆœ์œ„, ํฌ๋งท ํžŒํŠธ๋ฅผ ํ•จ๊ป˜ ์ฃผ์„ธ์š”." -->
<img
  src="/hero-banner.webp"
  width="1200"
  height="600"
  style="aspect-ratio: 2 / 1; width: 100%; height: auto;"
  fetchpriority="high"
  alt="๋ฉ”์ธ ๋ฐฐ๋„ˆ"
>

width์™€ height๋Š” CLS๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „ ๊ณต๊ฐ„์„ ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. fetchpriority="high"๋Š” LCP ํ›„๋ณด์ฒ˜๋Ÿผ ์ฒซ ํ™”๋ฉด์—์„œ ์ค‘์š”ํ•œ ์ด๋ฏธ์ง€์—๋งŒ ์‹ ์ค‘ํ•˜๊ฒŒ ์“ฐ๊ณ , ๋‚˜๋จธ์ง€ ์ด๋ฏธ์ง€๋Š” ๊ธฐ๋ณธ ์šฐ์„ ์ˆœ์œ„๋‚˜ lazy loading์— ๋งก๊ธฐ๋Š” ํŽธ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (Self-Check)

  • Level 1 (Junior): "LCP๋Š” ๋กœ๋”ฉ ์†๋„, CLS๋Š” ํ™”๋ฉด ํ”๋“ค๋ฆผ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๋ฅผ ์ž‘๊ฒŒ ๋งŒ๋“ค๊ณ  ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•˜๋ฉด ์ข‹์•„์ง‘๋‹ˆ๋‹ค."
  • Level 2 (Senior): "LCP ๊ฐœ์„ ์„ ์œ„ํ•ด ์„œ๋ฒ„ ์‘๋‹ต ์‹œ๊ฐ„(TTFB) ๋‹จ์ถ•, ๋ถˆํ•„์š”ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์ฐจ๋‹จ, ์ด๋ฏธ์ง€ ์ตœ์ ํ™”(WebP, Lazy Loading) ์ „๋žต์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค. CLS ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์ด๋ฏธ์ง€์™€ ๊ด‘๊ณ  ์˜์—ญ์˜ Aspect-ratio ํ™•๋ณด, ํฐํŠธ ๋กœ๋”ฉ ์ตœ์ ํ™”(font-display: swap) ๋“ฑ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค."
  • Level 3 (Specialist): "์‚ฌ์šฉ์ž ๊ธฐ๊ธฐ๋ณ„ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์— ๋”ฐ๋ฅธ 'Adaptive Loading' ์ „๋žต์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ธŒ๋ผ์šฐ์ €์˜ ์ „์ฒ˜๋ฆฌ ์ง€์‹œ์ž(preload, preconnect)๋ฅผ ์ „๋žต์ ์œผ๋กœ ๋ฐฐ์น˜ํ•˜์—ฌ ์ž„๊ณ„ ๊ฒฝ๋กœ(Critical Path)์˜ ์ž์›์„ ์„ ์ ํ•˜๋Š” ๊ณ ๋„ํ™”๋œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค."

๋ฉด์ ‘ ์งˆ๋ฌธ 2. ๋ฆฌ์•กํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฝ”๋“œ ๋ถ„ํ• (Code Splitting)์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ, ์ด๋ฅผ ํ†ตํ•ด ์–ป๋Š” ์ •๋Ÿ‰์ ์ธ ์ด์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๐ŸŽฏ ์ถœ์ œ ์˜๋„

๋ถˆํ•„์š”ํ•œ ์ž์› ๋‚ญ๋น„๋ฅผ ์ค„์ด๋ ค๋Š” ์•„ํ‚คํ…์ฒ˜์  ๋…ธ๋ ฅ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ์— ๋‹ค์šด๋กœ๋“œํ•˜๋Š” '๋ชจ๋†€๋ฆฌ์‹ ๋ฒˆ๋“ค'์˜ ์œ„ํ—˜์„ฑ์„ ์ธ์ง€ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ Naive ๊ตฌํ˜„ (Bad Case)

์˜์ฒ ์ด๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ตœ์ƒ๋‹จ์—์„œ ์ •์ ์œผ๋กœ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค.

// ๐Ÿฃ ์˜์ฒ : "๋‚˜์ค‘์— ์“ธ ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ ๋ฏธ๋ฆฌ ๋‹ค ๋ถˆ๋Ÿฌ์˜ฌ๊ฒŒ์š”!"
import HeavyChart from './components/HeavyChart'; // โš ๏ธ 5MB ์งœ๋ฆฌ ์ฐจํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
import AdminPanel from './components/AdminPanel'; // โš ๏ธ ์ผ๋ฐ˜ ์œ ์ €๋Š” ์•ˆ ๋ณด๋Š” ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€
 
function App({ user }) {
  return (
    <div>
      <MainContent />
      <HeavyChart />
      {user.role === 'admin' ? <AdminPanel /> : null}
    </div>
  );
}

๐Ÿฆ ์˜ํ˜ธ์˜ ๋ฆฌ๋ทฐ ํฌ์ธํŠธ
"์˜์ฒ  ๋‹˜, ์ง‘ ์ด์‚ฌํ•  ๋•Œ ๋ชจ๋“  ์ง์„ ํ•œ ์†์— ๋“ค๊ณ  ๊ฐ€๋ ค๋Š” ๊ฑฐ๋ž‘ ๊ฐ™์•„์š”. 1๋…„์— ํ•œ ๋ฒˆ ์“ฐ๋Š” ๋ฌผ๊ฑด(๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€)์€ ์ฐฝ๊ณ ์— ๋‘์—ˆ๋‹ค๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งŒ ๊บผ๋‚ด ์จ์•ผ์ฃ . ๊ทธ๊ฒŒ ๋ฐ”๋กœ Dynamic Import์ž…๋‹ˆ๋‹ค."

๐Ÿฆ ์˜ํ˜ธ์˜ ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ (Good Case)

์˜ํ˜ธ ๋ฆฌ๋“œ๊ฐ€ React.lazy์™€ Suspense๋ฅผ ํ™œ์šฉํ•œ ๋ฒˆ๋“ค ๋‹ค์ด์–ดํŠธ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

// ๐Ÿฆ ์˜ํ˜ธ: "์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ ํŽ˜์ด์ง€์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ์ฝ”๋“œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ๋งˆ์„ธ์š”."
 
import { lazy, Suspense } from 'react';
 
// โœ… ํ•„์š”ํ•  ๋•Œ๋งŒ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์  ์ž„ํฌํŠธ
const HeavyChart = lazy(() => import('./components/HeavyChart'));
const AdminPanel = lazy(() => import('./components/AdminPanel'));
 
function App({ user }) {
  return (
    <Suspense fallback={<Skeleton />}>
      <MainContent />
      {/* ์ฐจํŠธ์™€ ๊ด€๋ฆฌ์ž ์ฝ”๋“œ๋Š” ์ด ๊ฒฝ๋กœ๊ฐ€ ์‹ค์ œ๋กœ ํ•„์š”ํ•ด์งˆ ๋•Œ ๋ณ„๋„ chunk๋กœ ๊ฐ€์ ธ์˜จ๋‹ค. */}
      {user.showChart ? <HeavyChart /> : null}
      {user.role === 'admin' ? <AdminPanel /> : null}
    </Suspense>
  );
}

์ฝ”๋“œ ๋ถ„ํ• ์€ ์ดˆ๊ธฐ JavaScript๋ฅผ ์ค„์ด๋Š” ๋ฐ ๋„์›€์ด ๋˜์ง€๋งŒ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ์ •๋‹ต์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ž์ฃผ ์ง€๋‚˜๊ฐ€๋Š” ๊ฒฝ๋กœ์— ์ž‘์€ chunk๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์ง€๋ฉด ์š”์ฒญ๊ณผ ๋กœ๋”ฉ ๊ฒฝ๊ณ„๊ฐ€ ๋Š˜ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ฒˆ๋“ค ๋ถ„์„๊ณผ ์‹ค์ œ ์‚ฌ์šฉ์ž ํ๋ฆ„์„ ํ•จ๊ป˜ ๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (Self-Check)

  • Level 1 (Junior): "React.lazy๋ฅผ ์“ฐ๋ฉด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚˜์ค‘์— ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์–ด์„œ ์ดˆ๊ธฐ ์†๋„๊ฐ€ ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค."
  • Level 2 (Senior): "๋ผ์šฐํŠธ ๋‹จ์œ„(Route-based) ๋ฐ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„(Component-based) ๋ถ„๋ฆฌ ์ „๋žต์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด TBT(Total Blocking Time)์™€ TTI(Time to Interactive) ์ง€ํ‘œ๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Œ์„ ์ •๋Ÿ‰์ ์œผ๋กœ ์–ธ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค."
  • Level 3 (Specialist): "๋ฒˆ๋“ค ๋ถ„์„ ๋„๊ตฌ(Webpack Bundle Analyzer ๋“ฑ)๋ฅผ ํ™œ์šฉํ•ด ์ค‘๋ณต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , 'Shared Chunk' ์ „๋žต์„ ํ†ตํ•ด ๊ณตํ†ต ๋ชจ๋“ˆ์˜ ์บ์‹ฑ ํšจ์œจ์„ ๋†’์ด๋Š” ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(RSC)๋ฅผ ํ™œ์šฉํ•ด ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณด๋‚ด๋Š” JS ์ž์ฒด๋ฅผ ์ค„์ด๋Š” ์ตœ์ƒ์œ„ ์ตœ์ ํ™” ๊ฐœ๋…์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค."

๋ฉด์ ‘ ์งˆ๋ฌธ 145. ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ(CRP) ์ตœ์ ํ™”๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: HTML/CSS๊ฐ€ ํ™”๋ฉด์— ๊ทธ๋ ค์ง€๊ธฐ๊นŒ์ง€์˜ ์ „ ๊ณผ์ •์„ ์ดํ•ดํ•˜๊ณ  ๋ณ‘๋ชฉ์„ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: CRP ์ตœ์ ํ™”๋Š” DOM๊ณผ CSSOM ์ƒ์„ฑ์„ ๋ฐฉํ•ดํ•˜๋Š” ์š”์†Œ(Critical Resources)๋ฅผ ์ค„์ด๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. CSS๋Š” <head> ์ƒ๋‹จ์— ๋ฐฐ์น˜ํ•˜์—ฌ ๋ Œ๋”๋ง ์ฐจ๋‹จ์„ ๋ฐฉ์ง€ํ•˜๊ณ , JS๋Š” async๋‚˜ defer ์†์„ฑ์„ ์จ์„œ ํŒŒ์‹ฑ์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ํ•„์š”ํ•œ ๊ธฐ๊ธฐ์—์„œ๋งŒ ํŠน์ • CSS๋ฅผ ๋กœ๋“œํ•˜๊ฒŒ ํ•˜๊ฑฐ๋‚˜, ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋ง์„ ํ†ตํ•ด ์ตœ์ดˆ ํ™”๋ฉด(Above the fold)์— ํ•„์š”ํ•œ ์Šคํƒ€์ผ์„ ๋น ๋ฅด๊ฒŒ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ฒ•์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

๋ฉด์ ‘ ์งˆ๋ฌธ 152. ์„œ๋น„์Šค ์›Œ์ปค(Service Worker)๋ฅผ ํ™œ์šฉํ•œ ์„ฑ๋Šฅ ๊ฐœ์„  ์‚ฌ๋ก€๋ฅผ ๋“ค์–ด๋ณด์„ธ์š”.

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ๋„คํŠธ์›Œํฌ ๊ณ„์ธต์—์„œ์˜ ์ตœ์ ํ™”์™€ ์˜คํ”„๋ผ์ธ ๊ฒฝํ—˜(PWA)์— ๋Œ€ํ•œ ์ดํ•ด๋„๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: ์„œ๋น„์Šค ์›Œ์ปค๋Š” ๋ธŒ๋ผ์šฐ์ €์™€ ๋„คํŠธ์›Œํฌ ์‚ฌ์ด์˜ ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ •์  ์ž์‚ฐ(JS, CSS, Image)์„ ๋กœ์ปฌ์— ์ „๋žต์ ์œผ๋กœ ์บ์‹ฑํ•˜์—ฌ ์žฌ๋ฐฉ๋ฌธ ์‹œ ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋„คํŠธ์›Œํฌ ๋ถˆ์•ˆ์ • ์‹œ์—๋„ ์˜คํ”„๋ผ์ธ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜, ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํŽ˜์นญํ•˜์—ฌ ์ตœ์‹  ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋Š” 'Background Sync'๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ฒด๊ฐ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉด์ ‘ ์งˆ๋ฌธ 160. ์›น ํฐํŠธ ๋กœ๋”ฉ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ํฐํŠธ ๋กœ๋”ฉ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ํ…์ŠคํŠธ ๋ฏธํ‘œ์‹œ(FOIT)๋‚˜ ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ๊ธ€๊ผด ๋ณ€๊ฒฝ(FOUT) ๋ฌธ์ œ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: ์ฒซ์งธ, preload๋ฅผ ํ†ตํ•ด ํฐํŠธ ํŒŒ์ผ์„ ์šฐ์„ ์ˆœ์œ„ ์žˆ๊ฒŒ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ๋‘˜์งธ, font-display: swap; ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํฐํŠธ ๋กœ๋”ฉ ์ค‘์—๋Š” ์‹œ์Šคํ…œ ํฐํŠธ๋ฅผ ๋จผ์ € ๋ณด์—ฌ์คŒ์œผ๋กœ์จ LCP ์ง€ํ‘œ๋ฅผ ๋ฐฉ์–ดํ•ฉ๋‹ˆ๋‹ค. ์…‹์งธ, ํฐํŠธ ํŒŒ์ผ์˜ ์„œ๋ธŒ์…‹(Subset)์„ ๋งŒ๋“ค์–ด ํ•„์š”ํ•œ ์–ธ์–ด๋งŒ ํฌํ•จํ•˜๊ฑฐ๋‚˜ WOFF2์™€ ๊ฐ™์€ ์••์ถ•๋ฅ  ๋†’์€ ํฌ๋งท์„ ์‚ฌ์šฉํ•˜์—ฌ ์šฉ๋Ÿ‰์„ ์ค„์ด๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. LCP ๊ฐœ์„ ์„ ์„ค๋ช…ํ•  ๋•Œ ๋‹จ์ˆœํžˆ "์ด๋ฏธ์ง€๋ฅผ ์ค„์ธ๋‹ค"๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•ด์•ผ ํ•  ๋‚ด์šฉ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

โœ… ์ •๋‹ต: ๊ฐ€์žฅ ํฐ ์ฝ˜ํ…์ธ ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‹๋ณ„ํ•˜๊ณ , ์ด๋ฏธ์ง€ ํฌ๊ธฐ/ํฌ๋งท/์šฐ์„ ์ˆœ์œ„/์„œ๋ฒ„ ์‘๋‹ต ์‹œ๊ฐ„์„ ํ•จ๊ป˜ ์ค„์ด๋Š” ์ „๋žต

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: LCP๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ฃผ์š” ์ฝ˜ํ…์ธ ๋ฅผ ์–ธ์ œ ๋ณด๋А๋ƒ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€ ์ตœ์ ํ™”๋ฟ ์•„๋‹ˆ๋ผ preloading, fetchpriority, CDN, SSR ์‘๋‹ต ์‹œ๊ฐ„๋„ ํ•จ๊ป˜ ๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: Lighthouse ์ ์ˆ˜๋งŒ ์™ธ์šฐ๋ฉด ์‹ค์ œ ๋ณ‘๋ชฉ์ด ๋„คํŠธ์›Œํฌ์ธ์ง€ ๋ Œ๋”๋ง์ธ์ง€, ์ด๋ฏธ์ง€ ์ž๋ฆฌ ์˜ˆ์•ฝ์ธ์ง€ ์„ค๋ช…ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: LCP๋Š” ๊ฐ€์žฅ ํฐ ์š”์†Œ์˜ ์—ฌํ–‰ ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

Q2. CLS๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ด๋ฏธ์ง€์— width์™€ height ๋˜๋Š” aspect-ratio๋ฅผ ์ฃผ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

โœ… ์ •๋‹ต: ๋ฆฌ์†Œ์Šค๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์—๋„ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ณต๊ฐ„์„ ์˜ˆ์•ฝํ•ด ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ ˆ์ด์•„์›ƒ ์ด๋™์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ๋ชจ๋ฅด๋ฉด ๋กœ๋”ฉ ํ›„ ๋ฐ•์Šค ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉฐ ์ฃผ๋ณ€ ์ฝ˜ํ…์ธ ๊ฐ€ ๋ฐ€๋ฆฝ๋‹ˆ๋‹ค. ์ด ํ”๋“ค๋ฆผ์€ ์‚ฌ์šฉ์ž์˜ ํด๋ฆญ ์‹ค์ˆ˜์™€ ๋ถˆ์‹ ์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: ๋‹จ์ง€ ์˜ˆ์œ ๋น„์œจ์„ ๋งž์ถ”๊ธฐ ์œ„ํ•œ ์†์„ฑ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ ์•ˆ์ •์„ฑ์„ ์œ„ํ•œ ์„ฑ๋Šฅ ์†์„ฑ์ž…๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ๋Šฆ๊ฒŒ ๋œฐ ์š”์†Œ์ผ์ˆ˜๋ก ์ž๋ฆฌ๋ถ€ํ„ฐ ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค.

Q3. ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„: ์ฝ”๋“œ ๋ถ„ํ• ์„ ์ ์šฉํ•˜๊ธฐ ์ „ ๊ฐ€์žฅ ๋จผ์ € ํ™•์ธํ•  ๊ฒƒ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

โœ… ์ •๋‹ต: ์ดˆ๊ธฐ ๋ Œ๋”๋ง์— ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฌด๊ฑฐ์šด ๊ธฐ๋Šฅ์ด ๋ฒˆ๋“ค์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ bundle analyzer์™€ ์‹ค์ œ ์‚ฌ์šฉ์ž ํ๋ฆ„์œผ๋กœ ํ™•์ธํ•œ๋‹ค

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: ์ฝ”๋“œ ๋ถ„ํ• ์€ ์ดˆ๊ธฐ JS ๋น„์šฉ์„ ์ค„์ด๋Š” ๋ฐ ์ข‹์ง€๋งŒ, ๋„ˆ๋ฌด ์ž˜๊ฒŒ ๋‚˜๋ˆ„๋ฉด ์š”์ฒญ ์ˆ˜์™€ ๋กœ๋”ฉ ๊ฒฝ๊ณ„๊ฐ€ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์‚ฌ์šฉ์ž ์—ฌ์ •์—์„œ ๋Šฆ๊ฒŒ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ dynamic import๋กœ ๋ฐ”๊พธ๋Š” ๊ฑด ์ „๋žต์ด ์•„๋‹ˆ๋ผ ๋ถ„์‚ฐ๋œ ์ง€์—ฐ์ž…๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ์ง€๊ธˆ ํ•„์š”ํ•œ ์ฝ”๋“œ์™€ ๋‚˜์ค‘์— ํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜์€ ์„ฑ๋Šฅ์„ "์ ์ˆ˜ ์˜ฌ๋ฆฌ๊ธฐ"๊ฐ€ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ์ผ๋กœ ๋‹ค์‹œ ๋ณด๊ฒŒ ๋๋‹ค. LCP, CLS ๊ฐ™์€ ์ง€ํ‘œ๊ฐ€ ์ˆซ์ž์ฒ˜๋Ÿผ ๋ณด์˜€์ง€๋งŒ, ์‚ฌ์‹ค์€ ์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ์‚ฌ์šฉ์ž๊ฐ€ ์ฒซ ํ™”๋ฉด์„ ๋ฏฟ๊ณ  ํด๋ฆญํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์•ฝ์†์ด์—ˆ๋‹ค.

๐Ÿ’ก "์„ฑ๋Šฅ ์ตœ์ ํ™”๋Š” ๋น ๋ฅธ ์ฒ™ํ•˜๋Š” ๊ธฐ์ˆ ์ด ์•„๋‹ˆ๋ผ, ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์•„๋„ ๋˜๋Š” ์ด์œ ๋ฅผ ํ•˜๋‚˜์”ฉ ๋งŒ๋“œ๋Š” ์ผ์ด๋‹ค."

๋‹ค์Œ๋ถ€ํ„ฐ๋Š” "๋А๋ ค์š”"๋ผ๋Š” ์ œ๋ณด๋ฅผ ๋ฐ›์œผ๋ฉด Lighthouse ์ ์ˆ˜๋งŒ ์ฐ์ง€ ๋ง๊ณ , ์–ด๋–ค ์‚ฌ์šฉ ํ๋ฆ„์—์„œ ์–ด๋–ค ์ง€ํ‘œ๊ฐ€ ํ”๋“ค๋ฆฌ๋Š”์ง€ ๋จผ์ € ์ ์–ด์•ผ๊ฒ ๋‹ค. ์˜์ฒ ์ด ์ด์ œ ์„ฑ๋Šฅ์„ ๊ฐ์ƒ์ด ์•„๋‹ˆ๋ผ ์ฆ๊ฑฐ๋กœ ๋งํ•˜๋Š” ๊ฐœ๋ฐœ์ž์— ๊ฐ€๊นŒ์›Œ์ง€๊ณ  ์žˆ๋‹ค.