๊น๋ฐ์ด๋ ํ์ (FOUC์ FOUT ํ์) ๋ธ๋ก๊ทธ ์ฌ์ดํธ ์ฒ์ ํ๋ฉด ๋ฌธ์ ํํค์น๊ธฐ
๋ธ๋ก๊ทธ ์ฒซ ํ๋ฉด ๋ก๋ฉ ์ ๋ฐ์ํ๋ ๊น๋ฐ์ ํ์(FOUC/FOUT)์ ๋ถ์ํ๊ณ , Critical CSS ์ธ๋ผ์ธ, ์น ํฐํธ preload, ์ค์ผ๋ ํค ๋ก๋ฉ ๋ฑ์ผ๋ก ์ฌ์ฉ์ ๊ฒฝํ(UX)๊ณผ CLS(Cumulative Layout Shift)๋ฅผ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์๋ดํฉ๋๋ค.
์น ์ฑ๋ฅ ์งํ์ธ Core Web Vitals ์ค CLS์ ์น๋ช ์ ์ธ ์ํฅ์ ๋ฏธ์น๋ FOUC์ FOUT ํ์์ ์๋ฆฌ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ํจ๊ป ์ดํด๋ด ๋๋ค..
FOUC์ FOUT ์ ์: ๋ถ์์ ํ ์น ๊ฒฝํ์ ์์ธ
๋ธ๋ก๊ทธ ์คํจ์ ์์ ํ๊ฑฐ๋ ์ฌ์ดํธ๋ฅผ ์ ์ํ๊ฑฐ๋ ์์ ํ ๋ ๋ฐ๋์ ์ดํดํด์ผ ํ๋ FOUC(Flash of Unstyled Content)์ FOUT(Flash of Unstyled Text) ํ์์, CSS, Critical CSS, ์น ํฐํธ ๋ฑ ์คํ์ผ ๋ฆฌ์์ค๊ฐ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง ๊ณผ์ ์์ DOM๊ณผ CSSOM์ด ์์ ํ ๊ตฌ์ถ๋๊ธฐ ์ ์ ๋ก๋๋๊ฑฐ๋ ์ ์ฉ๋ ๋ ๋ฐ์ํฉ๋๋ค.

์ด๋ก ์ธํด ์ด๊ธฐ ํ๋ฉด ๊น๋ฐ์, ์คํ์ผ ์๋ ์ฝํ ์ธ ๋ ธ์ถ, ์น ํ์ด์ง ๋ ์ด์์ ์ด๋(Layout Shift)๊ณผ ๊ฐ์ ์๊ฐ์ ๋ถ์์ ํ์์ด ๋ํ๋๋ฉฐ, ํนํ ๋ธ๋ก๊ทธ ์ฒซ ํ๋ฉด ๋ก๋ฉ ์ ์ฌ์ฉ์ ๊ฒฝํ(UX)์ ์ ํ์ํฌ ์ ์์ต๋๋ค.
์งง์ ์๊ฐ์ ๊น๋นก์์ด๋ ๋ ์ด์์ ์ด๋์ ์ฌ์ฉ์์๊ฒ ํ์ด์ง๊ฐ ๋๋ฆฌ๊ณ ๋ฏธ์์ฑ์ด๋ผ๋ ์ธ์์ ์ฃผ์ด ์ฆ๊ฐ์ ์ธ ์ดํ(Bounce)์ ์ ๋ฐํ๋ฉฐ SEO์ ์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
1 FOUC (Flash of Unstyled Content) - ์คํ์ผ ์๋ ์ฝํ ์ธ ๊น๋นก์
FOUC(Flash of Unstyled Content)๋ ๋ธ๋ก๊ทธ ์ฒซ ๋ก๋ฉ ์ HTML ์ฝํ ์ธ ๊ฐ ์ธ๋ถ CSS ๋๋ Critical CSS ์ ์ฉ ์ ์ ์ ์คํ์ผ ์์ด ํ์๋๋ ํ์์ ๋๋ค.
๋ธ๋ผ์ฐ์ ๋ HTML ํ์ฑ์ ํตํด DOM(Document Object Model)์ ๋จผ์ ์์ฑํ์ง๋ง, CSSOM(CSS Object Model) ๊ตฌ์ถ์ด ์ง์ฐ๋๋ฉด ๋ ๋๋ง ์ฐจ๋จ ๋ฆฌ์์ค์ธ CSS ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์คํ์ผ ์๋ ์์ ์ฝํ ์ธ ๋ฅผ ๋จผ์ ๋ณด์ฌ์ฃผ๋ ๋ฐฉ๋ฒ์ ์ ํํ๋ฉฐ, ์ด ๊ณผ์ ์์ ํ์ด์ง ๊น๋ฐ์(Flash of Content), ์ด๊ธฐ ๋ก๋ฉ ๊น๋ฐ์๊ณผ ๊ฐ์ ์๊ฐ์ ๋ถ์์ ์ฑ์ด ๋ฐ์ํฉ๋๋ค.

2 FOUT (Flash of Unstyled Text) - ์น ํฐํธ ๋ก๋ ์ง์ฐ์ผ๋ก ์ธํ ํ ์คํธ ๊ต์ฒด
FOUT(Flash of Unstyled Text)๋ ์น ํฐํธ ํ์ผ์ด ๋ก๋๋๊ธฐ ์ , ํ ์คํธ๊ฐ ๊ธฐ๋ณธ ์์คํ ํฐํธ(Fallback Font)๋ก ์ ์ ํ์๋์๋ค๊ฐ ์น ํฐํธ๋ก ๊ต์ฒด๋ ๋ ๋ฐ์ํ๋ ํ์์ ๋๋ค.
์ด๋ฌํ ์น ํฐํธ ๋ก๋ ์ง์ฐ์ ํ์ด์ง ๊น๋ฐ์(Flash of Text), ํฐํธ ๊น๋นก์, ์ด๊ธฐ ๋ก๋ฉ ๊ธ๊ผด ๋ณ๊ฒฝ ๋ฑ ์๊ฐ์ ๋ถ์์ ์ฑ์ ์ ๋ฐํ๋ฉฐ, ํฐํธ ๊ต์ฒด ์ ๊ธ๊ผด ํฌ๊ธฐ, ์๊ฐ(Letter Spacing), ํ๊ฐ(Line Height) ๋ฑ์ด ๋ณํ๋ฉด์ ์ฃผ๋ณ ์์๊น์ง ํจ๊ป ์ด๋ํ๋ ๋ ์ด์์ ์ํํธ(Layout Shift)๋ฅผ ์ด๋ํฉ๋๋ค.
๋ธ๋ผ์ฐ์ ๋ ๋๋ง ์๋ฆฌ ์ดํด: FOUC/FOUT ๋ฐ์์ ๊ธฐ์ ์ ๊ทผ์
FOUC์ FOUT์ ๊ทผ๋ณธ์ ์ผ๋ก ํด๊ฒฐํ๋ ค๋ฉด ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋ง ๊ณผ์ ์ ์ดํดํด์ผ ํฉ๋๋ค. ์น ํ์ด์ง๋ Critical Rendering Path (CRP) ๋จ๊ณ๋ฅผ ๊ฑฐ์ณ ํ๋ฉด์ ๊ทธ๋ ค์ง๋๋ค.
| ๋จ๊ณ | ์ค๋ช | FOUC/FOUT ์ํฅ ์ง์ |
|---|---|---|
| DOM ํ์ฑ | HTML ์ฝ๋๋ฅผ ์ฝ์ด ๋ค์ฌ DOM ํธ๋ฆฌ๋ฅผ ์์ฑ. ํ์ด์ง์ ๊ตฌ์กฐ๋ฅผ ์ ์ํฉ๋๋ค. | ์ง์ ์ ์ธ ์ํฅ ์์ |
| CSS ํ์ฑ | ์ธ๋ถ CSS ํ์ผ์ ๋ก๋ํ๊ณ ํด์ํ์ฌ CSSOM ํธ๋ฆฌ๋ฅผ ์์ฑ. ํ์ด์ง์ ์คํ์ผ์ ์ ์ํฉ๋๋ค. | CSSOM ๊ตฌ์ถ ์ง์ฐ ์ FOUC ๋ฐ์ (๋ ๋๋ง ์ฐจ๋จ) |
| ๋ ๋ ํธ๋ฆฌ ์์ฑ | DOM๊ณผ CSSOM์ ๊ฒฐํฉํ์ฌ ๋ ๋ ํธ๋ฆฌ๋ฅผ ๋ง๋ญ๋๋ค. | ์คํ์ผ ์ ๋ณด ๋ถ์ถฉ๋ถ ์ FOUC ๋ ธ์ถ |
| ๋ ์ด์์ ๊ณ์ฐ | ๋ ๋ ํธ๋ฆฌ์ ๊ฐ ์์์ ๋ํ ์ ํํ ์์น์ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํฉ๋๋ค. (Reflow) | ํฐํธ๋ ์คํ์ผ์ ๋ค๋ฆ์ ์ ์ฉ์ผ๋ก ์ธํด ๋ ์ด์์ ์ด๋(CLS)์ด ๋ฐ์ํ๋ฉฐ FOUT์ด ๋๋๋ฌ์ง |
| ํ์ธํ | ๋ ์ด์์ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์์๋ฅผ ํฝ์ ๋จ์๋ก ํ๋ฉด์ ์ถ๋ ฅํฉ๋๋ค. | ์ต์ข ์คํ์ผ์ด ์ ์ฉ๋ ์ํ๋ก ํ์ |
๊ธฐ์ ์ ์ถ๋ก : CSSOM์ด ์์ฑ๋์ด์ผ ๋ ๋ ํธ๋ฆฌ๊ฐ ๊ตฌ์ฑ๋๊ณ ๋ ์ด์์ ๊ณ์ฐ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ฐ๋ผ์ CSS๋ ๋ ๋๋ง ์ฐจ๋จ ๋ฆฌ์์ค์ ๋๋ค. FOUT์ ํฐํธ ๋ฆฌ์์ค๊ฐ ๋ฆ๊ฒ ๋์ฐฉํ์ ๋ ๋ ์ด์์ ๊ณ์ฐ ๋จ๊ณ๋ฅผ ๋ค์ ๊ฐ์ ํ์ฌ ๋ถํ์ํ ๋ฆฌํ๋ก์ฐ(Reflow)๋ฅผ ์ ๋ฐํ๊ณ CLS ์ ์๋ฅผ ๋์ ๋๋ค.
FOUC ๊ทน๋ณต ์ ๋ต: CSS ๋ก๋ ์ต์ ํ (FCP ๊ฐ์ )
FOUC(Flash of Unstyled Content)๋ฅผ ๋ฐฉ์งํ๋ ํต์ฌ ์ ๋ต์ ๋ ๋๋ง ์ฐจ๋จ ์๊ฐ(Render-Blocking Time)์ ์ต์ํํ๊ณ , ์ด๊ธฐ ๋ ๋๋ง์ ํ์ํ ํ์ CSS(Critical CSS)๋ฅผ ๋ธ๋ผ์ฐ์ ์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค.
์ด๋ฅผ ํตํด First Contentful Paint(FCP)๋ฅผ ๊ฐ์ ํ์ฌ ํ์ด์ง ๊น๋ฐ์ ์์ด ์์ ์ ์ธ ์ฝํ ์ธ ํ์๋ฅผ ๋ณด์ฅํ ์ ์์ต๋๋ค.
1 CSS๋ฅผ head ํ๊ทธ ์ต์๋จ์ ๋ฐฐ์น (์ฐ์ ์์ ํ๋ณด)
CSS ํ์ผ์ HTML ๋ฌธ์์ head ํ๊ทธ ๋ด์, ๋ค๋ฅธ meta ํ๊ทธ๋ ์คํฌ๋ฆฝํธ๋ณด๋ค ์์ชฝ ์์์ ๋ฐฐ์นํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ํ์ผ์ ์์ฐจ์ ์ผ๋ก ํ์ฑํ๋ฏ๋ก, CSS๋ฅผ ๋จผ์ ๋ฐ๊ฒฌํ์ฌ ๋ค์ด๋ก๋๋ฅผ ์์ํ๊ณ CSSOM ๊ตฌ์ถ ์๊ฐ์ ๋จ์ถํฉ๋๋ค.
head
meta charset="UTF-8"
!-- CSS ํ์ผ์ ์ต๋ํ ์์ชฝ์ ๋ฐฐ์นํ์ฌ ์ฐ์ ์์๋ฅผ ๋์
๋๋ค --
link rel="stylesheet" href="main.css"
title์น ์ฑ๋ฅ ์ต์ ํ/title
/head
2 ํฌ๋ฆฌํฐ์ปฌ CSS (Critical CSS) ์ธ๋ผ์ธ ์ฝ์ ๋ฐ ๋น๋๊ธฐ ๋ก๋
์ด๊ธฐ ๋ทฐํฌํธ(Above-the-Fold) ๋ ๋๋ง์ ํ์ํ ์ต์ํ์ CSS(Critical CSS)๋ง์ ์ถ์ถํ์ฌ style ํ๊ทธ๋ก head ์์ ์ธ๋ผ์ธ์ผ๋ก ์ง์ ์ฝ์ ํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด HTTP ์์ฒญ ์์ด ๋ธ๋ผ์ฐ์ ๊ฐ ์ฆ์ ์คํ์ผ์ ์ ์ฉํ ์ ์์ด FOUC ๋ฐฉ์ง, ์น ํ์ด์ง ๊น๋ฐ์ ์ต์ํ, First Contentful Paint(FCP) ์ต์ ํ๊ฐ ๋์์ ์ด๋ฃจ์ด์ง๋๋ค.
๋๋จธ์ง CSS ํ์ผ์ link ํ๊ทธ์ media="print" ์์ฑ์ ์ฌ์ฉํ๊ณ , onload="this.media='all'" JavaScript ์ฝ๋๋ฅผ ํตํด ๋ก๋ ์๋ฃ ํ media๋ฅผ 'all'๋ก ๋ณ๊ฒฝํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋ํจ์ผ๋ก์จ ๋ ๋๋ง ์ฐจ๋จ ๋ฐฉ์ง์ ํ์ด์ง ๋ก๋ฉ ์ฑ๋ฅ ํฅ์์ ์ง์ํฉ๋๋ค.
head
style
/* Critical CSS: ์ด๊ธฐ ๋ทฐํฌํธ ์คํ์ผ */
body { margin: 0; font-family: sans-serif; }
.header { background: #1a1a1a; }
/style
!-- ๋๋จธ์ง CSS๋ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋ํ์ฌ ๋ ๋๋ง ์ฐจ๋จ ํด์ --
link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'"
/head
3 CSS ํ์ผ ์์ถ ๋ฐ ์ต์ํ (Minification & Compression)
CSS ํ์ผ์ ํฌ๊ธฐ๋ฅผ ์ค์ด๋ฉด ๋ค์ด๋ก๋ ์๊ฐ์ด ๋จ์ถ๋์ด CSSOM ๊ตฌ์ถ์ด ๋นจ๋ผ์ง๊ณ FOUC ๋ฐ์ ๊ฐ๋ฅ์ฑ์ ์ค์ ๋๋ค.
- Minification (์ต์ํ): ๋ถํ์ํ ๊ณต๋ฐฑ, ์ฃผ์, ์ค๋ณต ์ฝ๋๋ฅผ ์ ๊ฑฐํ์ฌ ํ์ผ ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค.
- Compression (์์ถ): ์๋ฒ ์ค์ (Nginx, Apache)์ ํตํด ์ ์ก๋๋ CSS ํ์ผ์ Gzip ๋๋ Brotli ์์ถ์ ์ ์ฉํ์ฌ ๋คํธ์ํฌ ์ ์ก๋์ ์ค์ ๋๋ค.
- Unused CSS ์ ๊ฑฐ: CSS ํธ๋ฆฌ ์์ดํน(Tree Shaking) ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ํ์ด์ง์์ ์ฌ์ฉํ์ง ์๋ CSS ๊ท์น์ ์ ๊ฑฐํฉ๋๋ค.
4 Anti-FOUC ํจํด (์ฝํ ์ธ ์จ๊ธฐ๊ธฐ)
CSS ๋ก๋๊ฐ ์๋ฃ๋ ๋๊น์ง ์ค์ ์ฝํ ์ธ ๋ ๋๋ง ์ง์ฐ ๋ฐฉ์ง๋ฅผ ์ํด ํ์ด์ง์ ํต์ฌ ์์๋ฅผ ์ผ์์ ์ผ๋ก ์จ๊ธฐ๋ ํจํด์ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ต์์ HTML ์์์ opacity: 0 ๋๋ visibility: hidden์ ์ ์ฉํ๊ณ , CSS ๋ก๋ ์๋ฃ ์์ ์ JavaScript๋ก ํด๋น ์คํ์ผ์ ์ ๊ฑฐํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์น ํ์ด์ง ๊น๋ฐ์(Flicker) ์ต์ํ, FOUC ๋ฐฉ์ง, ์ฌ์ฉ์ ๊ฒฝํ(UX) ์ ํ ๋ฐฉ์ง์ ํจ๊ป ๋ก๋ฉ ์ธ๋์ผ์ดํฐ๋ฅผ ์ ๊ณตํ์ฌ ๋ฐฉ๋ฌธ์๊ฐ ์ฝํ ์ธ ๋ก๋ฉ ์ํ๋ฅผ ์ง๊ด์ ์ผ๋ก ์ธ์ํ ์ ์์ต๋๋ค.
FOUT ๊ทน๋ณต ์ ๋ต: ์น ํฐํธ ๋ก๋ ์ต์ ํ (CLS ๋ฐฉ์ง)
FOUT ํ์์ ํฐํธ ํ์ผ ์์ฒด์ ๋ก๋ ์ง์ฐ ๋๋ฌธ์ ๋ฐ์ํ๋ฉฐ, ๋ ์ด์์ ์ด๋(CLS)์ ์ฃผ๋ฒ์ ๋๋ค. ํฐํธ ๋ก๋ ๋ฐฉ์์ ์ ์ดํ์ฌ CLS๋ฅผ ์ต์ํํด์ผ ํฉ๋๋ค.
1 font-display ์์ฑ ํ์ฉ: ํฐํธ ๋ก๋ ๋ฐฉ์ ์ ์ด
CSS์ @font-face ๊ท์น์ font-display ์์ฑ์ ์ง์ ํ์ฌ ๋ธ๋ผ์ฐ์ ์ ํฐํธ ๋ก๋ ์ ๋ต์ ๋ช ์์ ์ผ๋ก ์ ์ดํฉ๋๋ค.
| ์์ฑ | ์ค๋ช | ํจ๊ณผ ๋ฐ FOUT/FOIT ์ ๋ฐ ์ฌ๋ถ |
|---|---|---|
| swap | ์์คํ ํฐํธ(fallback)๋ก ์ฆ์ ํ ์คํธ๋ฅผ ํ์ํ๊ณ , ์น ํฐํธ ๋ก๋ ํ ๊ต์ฒด(swap)ํฉ๋๋ค. | ๋น ๋ฅธ ํ ์คํธ ํ์์ ์ ๋ฆฌ. ํฐํธ ๊ต์ฒด ์ FOUT ๋ฐ์ ๋ฐ CLS ์ ๋ฐ ๊ฐ๋ฅ. |
| block | ์งง์ ๊ธฐ๊ฐ ๋์ ํ ์คํธ๋ฅผ ์จ๊ธฐ๊ณ (์ฝ 3์ด๊น์ง), ๋ก๋๊ฐ ์๋ฃ๋ ๋๊น์ง ๋ณด์ด์ง ์๊ฒ ์ฒ๋ฆฌํฉ๋๋ค. | FOIT (Flash of Invisible Text) ๋ฐ์ ๊ฐ๋ฅ, ๊น๋นก์์ ์์ผ๋ ํ ์คํธ ์ง์ฐ์ผ๋ก UX ์ ํ. |
| fallback | ๋งค์ฐ ์งง์ ๋๊ธฐ ์๊ฐ(์ฝ 100ms) ๋์ ํ ์คํธ ์จ๊น ํ ์์คํ ํฐํธ ํ์. | FOUT๊ณผ FOIT์ ์ค๊ฐ ์ ๋ต. ํฐํธ ๋ก๋๊ฐ ๋งค์ฐ ๋๋ฆฐ ํ๊ฒฝ์์ CLS๋ฅผ ๋ฐฉ์ง. |
| optional | ์ฑ๋ฅ์ ์ต์ฐ์ ์ผ๋ก, ๋ธ๋ผ์ฐ์ ๊ฐ ๋คํธ์ํฌ ํ๊ฒฝ์ ๋ฐ๋ผ ํฐํธ ์ ์ฉ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. | ์ฑ๋ฅ ์ฐ์ ์ ์ ์ฉ. ํฐํธ ๋ก๋๊ฐ ๋๋ฆฌ๋ฉด ์์ ๋ค์ด๋ก๋ํ์ง ์๊ณ ์บ์๋์ง ์์ ์ ์์. |
CLS ์ต์ํ ํ: font-display: swap์ ์ฌ์ฉํ๋๋ผ๋, fallback ํฐํธ์ ์น ํฐํธ์ ํฌ๊ธฐ, ์๊ฐ, ํ๊ฐ์ CSS์ `size-adjust`, `ascent-override` ๋ฑ์ ์ฌ์ฉํ์ฌ ์ต๋ํ ์ ์ฌํ๊ฒ ๋ง์ถ๋ฉด CLS ๋ฐ์์ ์ต์ํํ ์ ์์ต๋๋ค.
2 link rel="preload" ์ฌ์ฉ: ํฐํธ ์ฐ์ ๋ค์ด๋ก๋
์น ํฐํธ ํ์ผ์ link rel="preload"๋ก ์ง์ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฅผ ๋ ๋๋ง ํ์ ๋ฆฌ์์ค(Critical Font Resource)๋ก ์ธ์ํ์ฌ ๋ค๋ฅธ ๋ฆฌ์์ค๋ณด๋ค ์ฐ์ ์ ์ผ๋ก ๋ค์ด๋ก๋ํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์น ํฐํธ ๋ก๋ฉ ์ง์ฐ ์ต์ํ, FOUT ๋ฐฉ์ง, ๋ ์ด์์ ์ด๋(Layout Shift) ๊ฐ์์ ํจ๊ป ์ด๊ธฐ ๋ ๋๋ง ์ ํ ์คํธ๊ฐ ๋น ๋ฅด๊ฒ ํ์๋์ด ํ์ด์ง ๊น๋ฐ์(Flicker) ์๋ ์์ ์ UX๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค
head
!-- ํฐํธ ํ์ผ์ CSS๋ณด๋ค ๋จผ์ ๋ก๋ํ์ฌ FOUT ๋ฐ์ ์๊ฐ ์ต์ํ --
link rel="preload" href="/fonts/CustomFont.woff2" as="font" type="font/woff2" crossorigin
link rel="stylesheet" href="main.css"
/head
์ฃผ์์ฌํญ: `crossorigin` ์์ฑ์ ํฐํธ ํ์ผ์ ๋ก๋ํ ๋ CORS(Cross-Origin Resource Sharing) ์ ์ฑ ์ ์ํด ํ์์ ์ผ๋ก ํฌํจ๋์ด์ผ ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๋ฐ ๋ ๋๋ง ์ต์ ํ๋ก FOUC/FOUT ๋ฐฉ์ง
JavaScript๋ DOM๊ณผ CSSOM์ ์ง์ ์ํฅ์ ์ฃผ๋ฏ๋ก ๋ ๋๋ง ์ฐจ๋จ ์์๊ฐ ๋ ์ ์์ต๋๋ค. ์ ์ ํ ๋ก๋ ์์์ ๋น๋๊ธฐ ์์ฑ์ ํ์ฉํ๋ฉด FOUC์ FOUT ๋ฐ์ ๊ฐ๋ฅ์ฑ์ ํฌ๊ฒ ์ค์ผ ์ ์์ต๋๋ค.
1. JavaScript ๋ก๋ ์์ ์ต์ ํ
JavaScript๊ฐ HTML ํ์ฑ์ ์ฐจ๋จํ์ฌ ๋ ๋๋ง์ ์ง์ฐ์ํค์ง ์๋๋ก ๋ก๋ ์์๋ฅผ ์ ์ดํด์ผ ํฉ๋๋ค.
- script ํ๊ทธ๋ฅผ body ๋์ ๋ฐฐ์น: HTML ํ์ฑ ๋ฐ CSSOM ๊ตฌ์ถ ํ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๋๋ก ํ์ฌ ์ด๊ธฐ ๋ ๋๋ง ์ฐจ๋จ ์๊ฐ์ ์ต์ํํฉ๋๋ค.
- async ์์ฑ: ์คํฌ๋ฆฝํธ ๋ค์ด๋ก๋๊ฐ HTML ํ์ฑ๊ณผ ๋์์ ์งํ๋์ง๋ง, ๋ค์ด๋ก๋ ์๋ฃ ์ฆ์ ์คํ์ ์ํด HTML ํ์ฑ์ ๋ฉ์ถฅ๋๋ค. (์์ ๋ณด์ฅ์ด ํ์ ์๋ ์คํฌ๋ฆฝํธ)
- defer ์์ฑ: ์คํฌ๋ฆฝํธ ๋ค์ด๋ก๋๊ฐ HTML ํ์ฑ๊ณผ ๋์์ ์งํ๋์ง๋ง, ์คํ์ HTML ํ์ฑ์ด ์๋ฃ๋ ํ (DOMContentLoaded ์ด๋ฒคํธ ์ง์ )์ ์์ ๋ณด์ฅ ํ์ ์คํ๋ฉ๋๋ค. (DOM ์กฐ์ ์คํฌ๋ฆฝํธ์ ์ ํฉ)
2. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR) ํ์ฉ: FOUC์ ๊ทผ๋ณธ์ ํด๊ฒฐ
SSR(Server-Side Rendering)์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง ์ด์ (Pre-rendering)์ ์๋ฒ์์ HTML์ ๋ฏธ๋ฆฌ ๊ตฌ์ฑํ๋ ๊ธฐ์ ๋ก, ์ด๊ธฐ ํ์ด์ง ๋ก๋ฉ ์ FOUC ๋ฐฉ์ง, FOUT ์ต์ํ, ๋ ์ด์์ ์ด๋(Layout Shift) ๊ฐ์๋ฅผ ํตํด Core Web Vitals ์ต์ ํ์ ๋น ๋ฅธ ์ฌ์ฉ์ ๊ฒฝํ(UX) ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- ์๋ฆฌ: ์๋ฒ์์ CSS์ ์ฝํ ์ธ ๋ฅผ ๊ฒฐํฉํ ์์ ํ HTML์ ์์ฑํ์ฌ ๋ธ๋ผ์ฐ์ ์ ์ ์กํฉ๋๋ค.
- ํจ๊ณผ: ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฏธ ์คํ์ผ์ด ์ ์ฉ๋ HTML์ ๋ฐ์ผ๋ฏ๋ก ๋ณ๋์ CSS ๋ก๋ ์ง์ฐ์ด ๋ฐ์ํ์ง ์์ FOUC๋ฅผ ๊ทผ๋ณธ์ ์ผ๋ก ๋ฐฉ์งํฉ๋๋ค. ๋ํ Time to First Byte(TTFB) ๊ฐ์ ์ ํตํด SEO ์ ์ ํฅ์์๋ ํฌ๊ฒ ๊ธฐ์ฌํฉ๋๋ค.
3. UX ์ค์ฌ ๋ก๋ฉ ์ ๋ต: ์ค์ผ๋ ํค ๋ก๋ฉ์ผ๋ก ์ฌ๋ฆฌ์ ์ฑ๋ฅ ์ต์ ํ
FOUC์ FOUT ํ์์ ์ต์ํํ๋ ์ต์ ํ ์ ๋ต๋ฟ๋ง ์๋๋ผ, ์ฌ์ฉ์ ๊ฒฝํ(UX) ๊ฐ์ ์ ์ํ ์น ํ์ด์ง ๋ก๋ฉ ์ ๋ต์ด ์ค์ํฉ๋๋ค.
ํนํ ์ค์ผ๋ ํค ๋ก๋ฉ(Skeleton Loading)์ ์ด๊ธฐ ๋ทฐํฌํธ์์ ์ฝํ ์ธ ๊ตฌ์กฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์ฌ์ฃผ์ด ๋ ์ด์์ ์ด๋(Layout Shift) ๊ฐ์, ์ฌ๋ฆฌ์ ๋ก๋ฉ ์๊ฐ ๋จ์ถ, Core Web Vitals ๊ฐ์ ์ ํจ๊ณผ์ ์ ๋๋ค
| ๋ก๋ฉ ์ ํ | ์ค๋ช | UX ํจ๊ณผ |
|---|---|---|
| ์คํผ๋(Spinner) | ํ์ ์์ด์ฝ์ผ๋ก ๋ก๋ ์ค์์ ํ์. | ์ฌ์ฉ์์๊ฒ ๊ธฐ๋ค๋ฆผ ๋ฉ์์ง ์ ๋ฌ. ๋ก๋ฉ ์๊ฐ์ ๋ํ ๋ถํ์ค์ฑ์ ์ฌ์ ํจ. |
| ์งํ๋ฐ(Progress Bar) | ๋ก๋ ์งํ๋ฅ ์ ์๊ฐ์ ์ผ๋ก ํ์. | ์์ ๋๊ธฐ ์๊ฐ ์ ๊ณต, ๋ถํ์ค์ฑ ๊ฐ์. |
| ์ค์ผ๋ ํค ๋ก๋ฉ | ์ค์ ์ฝํ ์ธ ์ ๊ตฌ์กฐ์ ๋ ์ด์์ ๋ผ๋๋ฅผ ํ์ ์์๋ก ๋ฏธ๋ฆฌ ๋ณด์ฌ์ค. | ๋ ์ด์์ ์ด๋ ์ต์ํ (CLS ๋ฐฉ์ง). ์ฌ์ฉ์์๊ฒ ์ฝํ ์ธ ๊ฐ ๋ก๋๋ ์์น๋ฅผ ๋ฏธ๋ฆฌ ๋ณด์ฌ์ฃผ์ด ์ธ์ง ๋ถํ ๊ฐ์ ๋ฐ ์ฌ๋ฆฌ์ ๋ก๋ฉ ์๊ฐ ๋จ์ถ. |
FAQ: FOUC์ FOUT ์ต์ ํ ์ค์
Q1. FOUC์ FOUT์ ์ฐจ์ด๋ฅผ ํ ๋ฌธ์ฅ์ผ๋ก ์ค๋ช ํ๋ฉด?
FOUC๋ CSS ์ ์ฉ ์ ์ฝํ ์ธ ๊น๋นก์, FOUT์ ์น ํฐํธ ๋ก๋ ์ ํ ์คํธ ํฐํธ ๊ต์ฒด๋ก ์ธํ ๊น๋นก์์ด๋ฉฐ, ๋ ๋ค ๋ ์ด์์ ์ด๋(CLS)์ ์ ๋ฐํฉ๋๋ค.
Q2. Critical CSS๋ฅผ ์ธ๋ผ์ธ์ผ๋ก ์ฌ์ฉํ๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
์ด๊ธฐ ๋ทฐํฌํธ ๋ ๋๋ง์ ํ์ํ ์ต์ CSS๋ฅผ ์ธ๋ผ์ธํ๋ฉด, ๋ณ๋์ HTTP ์์ฒญ์ ๊ฑด๋๋ฐ๊ณ ๋ฐ๋ก CSSOM์ ๊ตฌ์ถํ ์ ์์ด FCP๋ฅผ ๋น ๋ฅด๊ฒ ํ๊ณ FOUC๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
Q3. ์น ํฐํธ์์ font-display swap ์ ๋ต์ ์ฌ์ฉํ๋ฉด ์ด๋ค ํจ๊ณผ๊ฐ ์๋์?
ํ ์คํธ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ํ์ฌ FOIT๋ก ์ธํ ๊ณต๋ฐฑ์ ์์ ์ง๋ง, ์น ํฐํธ ๋ก๋ ํ ๊ต์ฒด ์ ํฐํธ์ ํฌ๊ธฐ ์ฐจ์ด๋ก ์ธํด FOUT์ด ๋ฐ์ํ๊ณ CLS๊ฐ ์ฆ๊ฐํ ์ ์์ต๋๋ค. UX์ ์ฑ๋ฅ์ ๊ท ํ ์๊ฒ ๊ฐ์ ํ๊ธฐ ์ํด ๋๋ฆฌ ์ฌ์ฉ๋ฉ๋๋ค.
Q4. ์ค์ผ๋ ํค ๋ก๋ฉ์ด FOUC์ FOUT ์ต์ ํ์ ๋์๋๋ ์ด์ ๋?
์ฝํ ์ธ ์ ์ต์ข ํฌ๊ธฐ์ ์์น๋ฅผ ๋ฏธ๋ฆฌ ํ๋ณดํ ๋ผ๋๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ๋๋ฌธ์, ์ค์ ์ฝํ ์ธ ๊ฐ ๋ก๋๋์ด๋ ๊ฐ์์ค๋ฌ์ด ๋ ์ด์์ ์ด๋(CLS)์ ๋ฐฉ์งํ๊ณ , ์ฌ์ฉ์๊ฐ ์๊ฐ์ ๋ถ์์ ์ฑ ์์ด ๋ก๋ฉ์ ๊ธฐ๋ค๋ฆด ์ ์๋๋ก ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
FOUC์ FOUT์ ํด๊ฒฐํ๋ ๊ฒ์ ๋จ์ํ ์๊ฐ์ ํ์ง ๋ฌธ์ ๋ฅผ ๋์ด์ Core Web Vitals์ CLS๋ฅผ ๊ฐ์ ํ๋ ํต์ฌ ์ ๋ต์ ๋๋ค. CLS๋ฅผ 0.1 ๋ฏธ๋ง์ผ๋ก ์ ์งํ๊ณ , FCP (First Contentful Paint) ๋ฐ LCP (Largest Contentful Paint) ์งํ ๊ฐ์ ์๋ ์ง์ ์ ์ธ ํจ๊ณผ๊ฐ ์์ต๋๋ค.
Critical CSS ์ธ๋ผ์ธ, `font-display` ์ค์ , `preload` ํ์ฉ, JavaScript ๋น๋๊ธฐ ๋ก๋, SSR ํ์ฉ, ๊ทธ๋ฆฌ๊ณ ์ค์ผ๋ ํค ๋ก๋ฉ๊ณผ ๊ฐ์ ๋ค๊ฐ์ ์ธ ์ ๋ต์ ์ข ํฉ์ ์ผ๋ก ์ ์ฉํด์ผ ํฉ๋๋ค. ์ด๋ฌํ ์ต์ ํ๋ ํ์ด์ง ๋ก๋ฉ ์๋๋ฅผ ๊ฐ์ ํ๊ณ , ์ฌ์ฉ์ ์ดํ๋ฅ ์ ์ค์ด๋ฉฐ, ๊ถ๊ทน์ ์ผ๋ก ์น์ฌ์ดํธ์ ์ ๋ฌธ์ฑ๊ณผ ์ ํ์จ์ ๋์ฌ ๋น์ฆ๋์ค ๊ฐ์น๋ฅผ ,๋์ด๋ ํต์ฌ ์์๊ฐ ๋ ๊ฒ์ ๋๋ค.