09. ๐ ์น ์ฑ๋ฅ ์ต์ ํ์ Core Web Vitals
๐ ๊ฐ์
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 ์์ฒด๋ฅผ ์ค์ด๋ ์ต์์ ์ต์ ํ ๊ฐ๋ ์ ์ ์ํฉ๋๋ค."
๐ ์ค์ ๋ณํ ์ง๋ฌธ (Related Variations)
๋ฉด์ ์ง๋ฌธ 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 ์ ์๋ง ์ฐ์ง ๋ง๊ณ , ์ด๋ค ์ฌ์ฉ ํ๋ฆ์์ ์ด๋ค ์งํ๊ฐ ํ๋ค๋ฆฌ๋์ง ๋จผ์ ์ ์ด์ผ๊ฒ ๋ค. ์์ฒ ์ด ์ด์ ์ฑ๋ฅ์ ๊ฐ์์ด ์๋๋ผ ์ฆ๊ฑฐ๋ก ๋งํ๋ ๊ฐ๋ฐ์์ ๊ฐ๊น์์ง๊ณ ์๋ค.