์น ์ปดํฌ๋ํธ์ ์ต๊ณ ์ฑ๋ฅ์ ๋์ด๋ด์ธ์. ์ด ๊ฐ์ด๋๋ ์ง์ฐ ๋ก๋ฉ๋ถํฐ ์๋์ฐ DOM๊น์ง, ์ต์ ํ๋ฅผ ์ํ ํฌ๊ด์ ์ธ ํ๋ ์์ํฌ์ ์คํ ๊ฐ๋ฅํ ์ ๋ต์ ์ ๊ณตํฉ๋๋ค.
์น ์ปดํฌ๋ํธ ์ฑ๋ฅ ํ๋ ์์ํฌ: ์ต์ ํ ์ ๋ต ๊ตฌํ ๊ฐ์ด๋
์น ์ปดํฌ๋ํธ๋ ํ๋ ์์ํฌ์ ๊ตฌ์ ๋ฐ์ง ์๋ ํ๋์ ์ธ ์น ๊ฐ๋ฐ์ ์ด์์ ๋๋ค. ์บก์ํ, ์ฌ์ฌ์ฉ์ฑ, ์ํธ์ด์ฉ์ฑ์ด๋ผ๋ ์ฅ์ ๋๋ถ์ ์ ์ธ๊ณ ํ๋ค์ ํ์ฅ ๊ฐ๋ฅํ ๋์์ธ ์์คํ ๊ณผ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์๊ฒ ๋์์ต๋๋ค. ํ์ง๋ง ํฐ ํ์๋ ํฐ ์ฑ ์์ด ๋ฐ๋ฆ ๋๋ค. ๊ฒ๋ณด๊ธฐ์๋ ๋ฌดํดํ ์์ฒด ํฌํจ ์ปดํฌ๋ํธ ๋ชจ์์ด๋ผ๋ ์ ์คํ๊ฒ ๊ด๋ฆฌํ์ง ์์ผ๋ฉด ์ฌ๊ฐํ ์ฑ๋ฅ ์ ํ๋ฅผ ์ด๋ํ์ฌ ๋ก๋ฉ ์๊ฐ ์ง์ฐ, ๋ฐ์ ์๋ ์ธํฐํ์ด์ค, ๋ต๋ตํ ์ฌ์ฉ์ ๊ฒฝํ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์ด๊ฒ์ ์ด๋ก ์ ์ธ ๋ฌธ์ ๊ฐ ์๋๋๋ค. ์ฌ์ฉ์ ์ฐธ์ฌ๋์ ์ ํ์จ๋ถํฐ ๊ตฌ๊ธ์ ์ฝ์ด ์น ๋ฐ์ดํ(Core Web Vitals)์ด ๊ฒฐ์ ํ๋ SEO ์์์ ์ด๋ฅด๊ธฐ๊น์ง ํต์ฌ ๋น์ฆ๋์ค ์งํ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ๋ฌธ์ ๋ ์ปค์คํ ์๋ฆฌ๋จผํธ(Custom Elements)์ ์๋ช ์ฃผ๊ธฐ, ์๋์ฐ DOM(Shadow DOM)์ ๋ ๋๋ง ๋ชจ๋ธ, HTML ํ ํ๋ฆฟ(HTML Templates)์ ์ ๋ฌ ๋ฐฉ์ ๋ฑ ์น ์ปดํฌ๋ํธ ์ฌ์์ ๊ณ ์ ํ ์ฑ๋ฅ ํน์ฑ์ ์ดํดํ๋ ๋ฐ ์์ต๋๋ค.
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋์์๋ ์ฒด๊ณ์ ์ธ ์น ์ปดํฌ๋ํธ ์ฑ๋ฅ ํ๋ ์์ํฌ๋ฅผ ์๊ฐํฉ๋๋ค. ์ด๋ ๊ฐ๋ฐ์์ ์์ง๋์ด๋ง ๋ฆฌ๋๊ฐ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์ฒด๊ณ์ ์ผ๋ก ์ง๋จ, ํด๊ฒฐ ๋ฐ ์๋ฐฉํ๋ ๋ฐ ๋์์ด ๋๋๋ก ์ค๊ณ๋ ๋ฉํ ๋ชจ๋ธ์ ๋๋ค. ์ฐ๋ฆฌ๋ ๋จํธ์ ์ธ ํ๊ณผ ์๋ น์ ๋์ด ์ด๊ธฐํ ๋ฐ ๋ ๋๋ง๋ถํฐ ๋คํธ์ํฌ ๋ก๋ฉ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ์ด๋ฅด๊ธฐ๊น์ง ๋ชจ๋ ๊ฒ์ ๋ค๋ฃจ๋ ์ ์ฒด์ ์ธ ์ ๋ต์ ๊ตฌ์ถํ ๊ฒ์ ๋๋ค. ๋จ์ผ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ถํ๋ , ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํ ๋ฐฉ๋ํ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๋ , ์ด ํ๋ ์์ํฌ๋ ์ฌ๋ฌ๋ถ์ ์ปดํฌ๋ํธ๊ฐ ๋จ์ง ๊ธฐ๋ฅ์ ์ผ ๋ฟ๋ง ์๋๋ผ ์๋ฑํ ๋น ๋ฅด๋๋ก ๋ณด์ฅํ๋ ๋ฐ ํ์ํ ์คํ ๊ฐ๋ฅํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ ๊ฒ์ ๋๋ค.
์น ์ปดํฌ๋ํธ์ ์ฑ๋ฅ ์งํ ์ดํดํ๊ธฐ
์ต์ ํ ์ ๋ต์ ๋ํด ์์๋ณด๊ธฐ ์ ์, ์ ์น ์ปดํฌ๋ํธ์์ ์ฑ๋ฅ์ด ํน๋ณํ ์ค์ํ๊ณ ์ด๋ค ๊ตฌ์ฒด์ ์ธ ๊ณผ์ ๊ฐ ์๋์ง ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ชจ๋๋ฆฌ์ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๋ฌ๋ฆฌ, ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ๋ ์ข ์ข "์ฒ ๊ฐ์ ์์ ์์ฒ๋ก ์ธํ ์ฃฝ์(death by a thousand cuts)" ์๋๋ฆฌ์ค๋ฅผ ๊ฒช์ต๋๋ค. ์ฆ, ์๊ณ ๋นํจ์จ์ ์ธ ๋ง์ ์ปดํฌ๋ํธ์ ๋์ ์ค๋ฒํค๋๊ฐ ํ์ด์ง๋ฅผ ๋ง๋น์ํค๋ ๊ฒ์ ๋๋ค.
์น ์ปดํฌ๋ํธ์์ ์ฑ๋ฅ์ด ์ค์ํ ์ด์
- ์ฝ์ด ์น ๋ฐ์ดํ(CWV)์ ๋ฏธ์น๋ ์ํฅ: ๊ฑด๊ฐํ ์ฌ์ดํธ๋ฅผ ์ํ ๊ตฌ๊ธ์ ์งํ๋ ์ปดํฌ๋ํธ ์ฑ๋ฅ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฐ์ต๋๋ค. ๋ฌด๊ฑฐ์ด ์ปดํฌ๋ํธ๋ ์ต๋ ์ฝํ ์ธ ํ ํ์ธํธ(LCP)๋ฅผ ์ง์ฐ์ํฌ ์ ์์ต๋๋ค. ๋ณต์กํ ์ด๊ธฐํ ๋ก์ง์ ์ต์ด ์ ๋ ฅ ์ง์ฐ(FID)์ด๋ ์๋ก์ด ๋ค์ ํ์ธํธ์ ๋ํ ์ํธ์์ฉ(INP)์ ์ฆ๊ฐ์ํฌ ์ ์์ต๋๋ค. ๊ณต๊ฐ์ ํ๋ณดํ์ง ์๊ณ ๋น๋๊ธฐ์ ์ผ๋ก ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ๋ ์ปดํฌ๋ํธ๋ ๋์ ๋ ์ด์์ ์ด๋(CLS)์ ์ ๋ฐํ ์ ์์ต๋๋ค.
- ์ฌ์ฉ์ ๊ฒฝํ(UX): ๋๋ฆฐ ์ปดํฌ๋ํธ๋ ๋ฒ๋ฒ ๊ฑฐ๋ฆฌ๋ ์คํฌ๋กค, ์ฌ์ฉ์ ์ํธ์์ฉ์ ๋ํ ํผ๋๋ฐฑ ์ง์ฐ, ์ ๋ฐ์ ์ผ๋ก ๋ฎ์ ํ์ง์ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ผ๋ ์ธ์์ ์ด๋ํฉ๋๋ค. ์ ์ธ๊ณ ์ธํฐ๋ท ์ฌ์ฉ์์ ์๋น ๋ถ๋ถ์ ์ฐจ์งํ๋ ์ ์ฌ์ ๊ธฐ๊ธฐ๋ ๋๋ฆฐ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ ์ฌ์ฉํ๋ ์ฌ์ฉ์์๊ฒ๋ ์ด๋ฌํ ๋ฌธ์ ๊ฐ ๋์ฑ ์ฆํญ๋ฉ๋๋ค.
- ํ์ฅ์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ: ์ฑ๋ฅ์ด ์ข์ ์ปดํฌ๋ํธ๋ ํ์ฅํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๋ฉด ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์๋น์๋ ๊ทธ ์ฑ๋ฅ ํน์ฑ์ ์์๋ฐ๊ฒ ๋ฉ๋๋ค. ์ ๋๋ก ์ต์ ํ๋์ง ์์ ๋จ์ผ ์ปดํฌ๋ํธ๊ฐ ์๋ฐฑ ๊ฐ์ ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ณ๋ชฉ ํ์์ ์ผ์ผํฌ ์ ์์ต๋๋ค.
์น ์ปดํฌ๋ํธ ์ฑ๋ฅ์ ๊ณ ์ ํ ๊ณผ์
์น ์ปดํฌ๋ํธ๋ ๊ธฐ์กด ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ์๋ ๋ค๋ฅธ ๊ณ ์ ํ ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ์๋์ฐ DOM ์ค๋ฒํค๋: ์๋์ฐ DOM์ ์บก์ํ์ ํ๋ฅญํ์ง๋ง ๊ณต์ง๋ ์๋๋๋ค. ์๋์ฐ ๋ฃจํธ๋ฅผ ์์ฑํ๊ณ , ๊ทธ ์์์ CSS๋ฅผ ํ์ฑ ๋ฐ ์ค์ฝํํ๊ณ , ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ์ค๋ฒํค๋๊ฐ ์ถ๊ฐ๋ฉ๋๋ค. ์ด๋ฒคํธ๊ฐ ์๋์ฐ DOM์์ ๋ผ์ดํธ DOM์ผ๋ก ๋ฒ๋ธ๋ง๋๋ ์ด๋ฒคํธ ๋ฆฌํ๊ฒํ (event retargeting) ๋ํ ์์ง๋ง ์ธก์ ๊ฐ๋ฅํ ๋น์ฉ์ด ๋ฐ์ํฉ๋๋ค.
- ์ปค์คํ
์๋ฆฌ๋จผํธ ์๋ช
์ฃผ๊ธฐ ํซ์คํ: ์ปค์คํ
์๋ฆฌ๋จผํธ ์๋ช
์ฃผ๊ธฐ ์ฝ๋ฐฑ(
constructor
,connectedCallback
,disconnectedCallback
,attributeChangedCallback
)์ ๊ฐ๋ ฅํ ํ ์ด์ง๋ง, ์ ์ฌ์ ์ธ ์ฑ๋ฅ ํจ์ ์ด๊ธฐ๋ ํฉ๋๋ค. ์ด๋ฌํ ์ฝ๋ฐฑ, ํนํconnectedCallback
๋ด์์ ๋ฌด๊ฒ๊ณ ๋๊ธฐ์ ์ธ ์์ ์ ์ํํ๋ฉด ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๊ณ ๋ ๋๋ง์ ์ง์ฐ์ํฌ ์ ์์ต๋๋ค. - ํ๋ ์์ํฌ ์ํธ์ด์ฉ์ฑ: React, Angular ๋๋ Vue์ ๊ฐ์ ํ๋ ์์ํฌ ๋ด์์ ์น ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ๋ ์ถ๊ฐ์ ์ธ ์ถ์ํ ๊ณ์ธต์ด ์กด์ฌํฉ๋๋ค. ํ๋ ์์ํฌ์ ๋ณ๊ฒฝ ๊ฐ์ง ๋๋ ๊ฐ์ DOM ๋ ๋๋ง ๋ฉ์ปค๋์ฆ์ ์น ์ปดํฌ๋ํธ์ ์์ฑ(properties) ๋ฐ ์ดํธ๋ฆฌ๋ทฐํธ(attributes)์ ์ํธ์์ฉํด์ผ ํ๋ฉฐ, ์ด๋ ์ ์คํ๊ฒ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ๋๋๋ก ์ค๋ณต ์ ๋ฐ์ดํธ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์น ์ปดํฌ๋ํธ ์ต์ ํ๋ฅผ ์ํ ์ฒด๊ณ์ ์ธ ํ๋ ์์ํฌ
์ด๋ฌํ ๊ณผ์ ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ํด, ์ฐ๋ฆฌ๋ 5๊ฐ์ ๋ ํนํ ๊ธฐ๋ฅ ์์ ๊ตฌ์ถ๋ ํ๋ ์์ํฌ๋ฅผ ์ ์ํฉ๋๋ค. ๊ฐ ๊ธฐ๋ฅ์ ๋ ์ฆ๋ฅผ ํตํด ์ปดํฌ๋ํธ๋ฅผ ๋ถ์ํจ์ผ๋ก์จ ํฌ๊ด์ ์ธ ์ต์ ํ ์ ๊ทผ ๋ฐฉ์์ ๋ณด์ฅํ ์ ์์ต๋๋ค.
- ๊ธฐ๋ฅ 1: ์๋ช ์ฃผ๊ธฐ ๊ธฐ๋ฅ (์ด๊ธฐํ ๋ฐ ์ ๋ฆฌ) - ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋๊ณ , DOM์ ์ถ๊ฐ๋๊ณ , ์ ๊ฑฐ๋ ๋ ๋ฐ์ํ๋ ์ผ์ ์ด์ ์ ๋ง์ถฅ๋๋ค.
- ๊ธฐ๋ฅ 2: ๋ ๋๋ง ๊ธฐ๋ฅ (ํ์ธํธ ๋ฐ ๋ฆฌํ์ธํธ) - DOM ๊ตฌ์กฐ์ ์คํ์ผ๋ง์ ํฌํจํ์ฌ ์ปดํฌ๋ํธ๊ฐ ํ๋ฉด์ ์ด๋ป๊ฒ ๊ทธ๋ ค์ง๊ณ ์ ๋ฐ์ดํธ๋๋์ง๋ฅผ ๋ค๋ฃน๋๋ค.
- ๊ธฐ๋ฅ 3: ๋คํธ์ํฌ ๊ธฐ๋ฅ (๋ก๋ฉ ๋ฐ ์ ๋ฌ) - ์ปดํฌ๋ํธ์ ์ฝ๋์ ์์ฐ์ด ๋ธ๋ผ์ฐ์ ์ ์ด๋ป๊ฒ ์ ๋ฌ๋๋์ง๋ฅผ ๋ค๋ฃน๋๋ค.
- ๊ธฐ๋ฅ 4: ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฅ (๋ฆฌ์์ค ๊ด๋ฆฌ) - ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐฉ์ง ๋ฐ ์์คํ ๋ฆฌ์์ค์ ํจ์จ์ ์ธ ์ฌ์ฉ์ ๋ค๋ฃน๋๋ค.
- ๊ธฐ๋ฅ 5: ํด๋ง ๊ธฐ๋ฅ (์ธก์ ๋ฐ ์ง๋จ) - ์ฑ๋ฅ์ ์ธก์ ํ๊ณ ๋ณ๋ชฉ ํ์์ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋๊ตฌ์ ๊ธฐ์ ์ ํฌํจํฉ๋๋ค.
๊ฐ ๊ธฐ๋ฅ ๋ด์ ์คํ ๊ฐ๋ฅํ ์ ๋ต๋ค์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ๋ฅ 1: ์๋ช ์ฃผ๊ธฐ ์ต์ ํ ์ ๋ต
์ปค์คํ ์๋ฆฌ๋จผํธ ์๋ช ์ฃผ๊ธฐ๋ ์น ์ปดํฌ๋ํธ ๋์์ ํต์ฌ์ ๋๋ค. ์ด๋ฌํ ๋ฉ์๋๋ฅผ ์ต์ ํํ๋ ๊ฒ์ด ๊ณ ์ฑ๋ฅ์ ํฅํ ์ฒซ๊ฑธ์์ ๋๋ค.
connectedCallback
์์์ ํจ์จ์ ์ธ ์ด๊ธฐํ
connectedCallback
์ ์ปดํฌ๋ํธ๊ฐ DOM์ ์ฝ์
๋ ๋๋ง๋ค ํธ์ถ๋ฉ๋๋ค. ์ ์คํ๊ฒ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ๋ ๋๋ง์ ์ฝ๊ฒ ์ฐจ๋จํ ์ ์๋ ์ค์ํ ๊ฒฝ๋ก์
๋๋ค.
์ ๋ต: ๋ชจ๋ ๋นํ์์ ์ธ ์์
์ ์ง์ฐ์ํต๋๋ค. connectedCallback
์ ์ฃผ์ ๋ชฉํ๋ ๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ ์ปดํฌ๋ํธ๋ฅผ ์ต์ ์คํ ๊ฐ๋ฅํ ์ํ๋ก ๋ง๋๋ ๊ฒ์ด์ด์ผ ํฉ๋๋ค.
- ๋๊ธฐ์ ์์ ํผํ๊ธฐ: ์ด ์ฝ๋ฐฑ์์ ๋๊ธฐ์ ์ธ ๋คํธ์ํฌ ์์ฒญ์ด๋ ๋ฌด๊ฑฐ์ด ๊ณ์ฐ์ ์ ๋ ์ํํ์ง ๋ง์ธ์.
- DOM ์กฐ์ ์ง์ฐ: ๋ณต์กํ DOM ์ค์ ์ ์ํํด์ผ ํ๋ ๊ฒฝ์ฐ,
requestAnimationFrame
์ ์ฌ์ฉํ์ฌ ์ฒซ ํ์ธํธ ์ดํ๊น์ง ์ง์ฐ์ํค๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค๋ฅธ ์ค์ํ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํ๋ ๊ฒ์ ๋ง์ง ์์ต๋๋ค. - ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ง์ฐ ์ฐ๊ฒฐ: ์ฆ์ ํ์ํ ๊ธฐ๋ฅ์ ๋ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ง ์ฐ๊ฒฐํ์ธ์. ์๋ฅผ ๋ค์ด, ๋๋กญ๋ค์ด ๋ฉ๋ด์ ๋ํ ๋ฆฌ์ค๋๋
connectedCallback
์ด ์๋๋ผ ์ฌ์ฉ์๊ฐ ํธ๋ฆฌ๊ฑฐ์ ์ฒ์ ์ํธ์์ฉํ ๋ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
์์: ์ค์ํ์ง ์์ ์ค์ ์ง์ฐํ๊ธฐ
์ต์ ํ ์ :
connectedCallback() {
// Heavy DOM manipulation
this.renderComplexChart();
// Attaching many event listeners
this.setupEventListeners();
}
์ต์ ํ ํ:
connectedCallback() {
// Render a simple placeholder first
this.renderPlaceholder();
// Defer the heavy lifting until after the browser has painted
requestAnimationFrame(() => {
this.renderComplexChart();
this.setupEventListeners();
});
}
disconnectedCallback
์์์ ์ค๋งํธํ ์ ๋ฆฌ
์ค์ ๋งํผ์ด๋ ์ ๋ฆฌ๋ ์ค์ํฉ๋๋ค. ์ปดํฌ๋ํธ๊ฐ DOM์์ ์ ๊ฑฐ๋ ๋ ์ ๋๋ก ์ ๋ฆฌํ์ง ๋ชปํ๋ ๊ฒ์ ์ค๋ ์ง์๋๋ ๋จ์ผ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ (SPA)์์ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ฃผ์ ์์ธ์ ๋๋ค.
์ ๋ต: connectedCallback
์์ ์์ฑ๋ ๋ชจ๋ ๋ฆฌ์ค๋๋ ํ์ด๋จธ๋ฅผ ๊ผผ๊ผผํ๊ฒ ๋ฑ๋ก ํด์ ํฉ๋๋ค.
- ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ:
window
,document
๋๋ ๋ถ๋ชจ ๋ ธ๋์ ๊ฐ์ ์ ์ญ ๊ฐ์ฒด์ ์ถ๊ฐ๋ ๋ชจ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ ๋ช ์์ ์ผ๋ก ์ ๊ฑฐํด์ผ ํฉ๋๋ค. - ํ์ด๋จธ ์ทจ์: ํ์ฑํ๋
setInterval
๋๋setTimeout
ํธ์ถ์ ๋ชจ๋ ์ง์๋๋ค. - ๋คํธ์ํฌ ์์ฒญ ์ค๋จ: ์ปดํฌ๋ํธ๊ฐ ์์ํ์ง๋ง ๋ ์ด์ ํ์ํ์ง ์์ fetch ์์ฒญ์ด ์๋ ๊ฒฝ์ฐ,
AbortController
๋ฅผ ์ฌ์ฉํ์ฌ ์ทจ์ํฉ๋๋ค.
attributeChangedCallback
์ผ๋ก ์์ฑ ๊ด๋ฆฌํ๊ธฐ
์ด ์ฝ๋ฐฑ์ ๊ด์ฐฐ๋ ์์ฑ์ด ๋ณ๊ฒฝ๋ ๋ ์คํ๋ฉ๋๋ค. ๋ถ๋ชจ ํ๋ ์์ํฌ์ ์ํด ์ฌ๋ฌ ์์ฑ์ด ๋น ๋ฅด๊ฒ ์ฐ์์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ฉด ์ฌ๋ฌ ๋ฒ์ ๋น์ฉ์ด ๋ง์ด ๋๋ ๋ฆฌ๋ ๋๋ง ์ฃผ๊ธฐ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
์ ๋ต: ๋ ๋ ์ค๋์ฑ(render thrashing)์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ๋ฐ์ดํธ๋ฅผ ๋๋ฐ์ด์ค(debounce)ํ๊ฑฐ๋ ์ผ๊ด ์ฒ๋ฆฌํฉ๋๋ค.
๋ง์ดํฌ๋กํ์คํฌ(Promise.resolve()
)๋ ์ ๋๋ฉ์ด์
ํ๋ ์(requestAnimationFrame
)์ ์ฌ์ฉํ์ฌ ๋จ์ผ ์
๋ฐ์ดํธ๋ฅผ ์ค์ผ์ค๋งํจ์ผ๋ก์จ ์ด๋ฅผ ๋ฌ์ฑํ ์ ์์ต๋๋ค. ์ด๋ ์ฌ๋ฌ ์์ฐจ์ ์ธ ๋ณ๊ฒฝ์ ํ๋์ ๋จ์ผ ๋ฆฌ๋ ๋๋ง ์์
์ผ๋ก ํตํฉํฉ๋๋ค.
๊ธฐ๋ฅ 2: ๋ ๋๋ง ์ต์ ํ ์ ๋ต
์ปดํฌ๋ํธ๊ฐ DOM๊ณผ ์คํ์ผ์ ๋ ๋๋งํ๋ ๋ฐฉ์์ ์๋ง๋ ์ฑ๋ฅ ์ต์ ํ์ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ฏธ์น๋ ์์ญ์ผ ๊ฒ์ ๋๋ค. ์ด๊ณณ์์์ ์์ ๋ณํ๋ ํนํ ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง์์ ์ฌ๋ฌ ๋ฒ ์ฌ์ฉ๋ ๋ ์๋นํ ์ด๋์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ฑํ๋ ์คํ์ผ์ํธ(Adopted Stylesheets)๋ก ์๋์ฐ DOM ๋ง์คํฐํ๊ธฐ
์๋์ฐ DOM์ ์คํ์ผ ์บก์ํ๋ ํ์์ ์ธ ๊ธฐ๋ฅ์ด์ง๋ง, ๊ธฐ๋ณธ์ ์ผ๋ก ์ปดํฌ๋ํธ์ ๊ฐ ์ธ์คํด์ค๊ฐ ์์ฒด <style>
๋ธ๋ก์ ๊ฐ๊ฒ ๋๋ค๋ ์๋ฏธ์
๋๋ค. ํ์ด์ง์ 100๊ฐ์ ์ปดํฌ๋ํธ ์ธ์คํด์ค๊ฐ ์๋ค๋ฉด, ๋ธ๋ผ์ฐ์ ๋ ๋์ผํ CSS๋ฅผ 100๋ฒ ํ์ฑํ๊ณ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
์ ๋ต: ์ฑํ๋ ์คํ์ผ์ํธ(Adopted Stylesheets)๋ฅผ ์ฌ์ฉํ์ธ์. ์ด ์ต์ ๋ธ๋ผ์ฐ์ API๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋จ์ผ CSSStyleSheet
๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ฌ๋ฌ ์๋์ฐ ๋ฃจํธ์์ ๊ณต์ ํ ์ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๋ CSS๋ฅผ ํ ๋ฒ๋ง ํ์ฑํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ํฌ๊ฒ ์ค์ด๋ค๊ณ ์ปดํฌ๋ํธ ์ธ์คํด์คํ๊ฐ ๋นจ๋ผ์ง๋๋ค.
์์: ์ฑํ๋ ์คํ์ผ์ํธ ์ฌ์ฉํ๊ธฐ
// Create the stylesheet object ONCE in your module
const myComponentStyles = new CSSStyleSheet();
myComponentStyles.replaceSync(`
:host { display: block; }
.title { color: blue; }
`);
class MyComponent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
// Apply the shared stylesheet to this instance
shadowRoot.adoptedStyleSheets = [myComponentStyles];
}
}
ํจ์จ์ ์ธ DOM ์ ๋ฐ์ดํธ
์ง์ ์ ์ธ DOM ์กฐ์์ ๋น์ฉ์ด ๋ง์ด ๋ญ๋๋ค. ๋จ์ผ ํจ์ ๋ด์์ DOM์ ๋ฐ๋ณต์ ์ผ๋ก ์ฝ๊ณ ์ฐ๋ ๊ฒ์ "๋ ์ด์์ ์ค๋์ฑ(layout thrashing)"์ ์ ๋ฐํ ์ ์์ผ๋ฉฐ, ์ด๋ก ์ธํด ๋ธ๋ผ์ฐ์ ๋ ๋ถํ์ํ ์ฌ๊ณ์ฐ์ ์ํํ๊ฒ ๋ฉ๋๋ค.
์ ๋ต: DOM ์์ ์ ์ผ๊ด ์ฒ๋ฆฌํ๊ณ ํจ์จ์ ์ธ ๋ ๋๋ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํฉ๋๋ค.
- DocumentFragments ์ฌ์ฉ: ๋ณต์กํ DOM ํธ๋ฆฌ๋ฅผ ๋ง๋ค ๋, ๋จผ์ ์ฐ๊ฒฐ๋์ง ์์
DocumentFragment
์์ ๊ตฌ์ถํ์ธ์. ๊ทธ๋ฐ ๋ค์ ์ ์ฒด ํ๋๊ทธ๋จผํธ๋ฅผ ๋จ์ผ ์์ ์ผ๋ก DOM์ ์ถ๊ฐํฉ๋๋ค. - ํ ํ๋ฆฟ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ: ๊ตฌ๊ธ์ `lit-html`(Lit ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ ๋๋ง ๋ถ๋ถ)๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด๋ฅผ ์ํด ํน๋ณํ ์ ์๋์์ต๋๋ค. ํ๊ทธ๋ ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด๊ณผ ์ง๋ฅ์ ์ธ ๋น๊ต(diffing) ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ค์ ๋ก ๋ณ๊ฒฝ๋ DOM ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธํ๋ฏ๋ก, ์ปดํฌ๋ํธ์ ์ ์ฒด innerHTML์ ๋ค์ ๋ ๋๋งํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ํจ์จ์ ์ ๋๋ค.
์ฑ๋ฅ ์ข์ ํฉ์ฑ์ ์ํ ์ฌ๋กฏ ํ์ฉ
<slot>
์์๋ ์ฑ๋ฅ ์นํ์ ์ธ ๊ธฐ๋ฅ์
๋๋ค. ์ด๋ฅผ ํตํด ์ปดํฌ๋ํธ๊ฐ ํด๋น DOM์ ์์ ํ๊ฑฐ๋ ๊ด๋ฆฌํ ํ์ ์์ด ๋ผ์ดํธ DOM ์์์ ์ปดํฌ๋ํธ์ ์๋์ฐ DOM์ผ๋ก ํฌ์ํ ์ ์์ต๋๋ค. ์ด๋ ๋ณต์กํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ ์ปดํฌ๋ํธ๊ฐ DOM ๊ตฌ์กฐ๋ฅผ ์ง์ ๋ค์ ์์ฑํ๊ฒ ํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋น ๋ฆ
๋๋ค.
๊ธฐ๋ฅ 3: ๋คํธ์ํฌ ๋ฐ ๋ก๋ฉ ์ ๋ต
์ปดํฌ๋ํธ๊ฐ ๋ด๋ถ์ ์ผ๋ก ์๋ฒฝํ๊ฒ ์ต์ ํ๋์ด ์๋๋ผ๋, ์ฝ๋๊ฐ ๋คํธ์ํฌ๋ฅผ ํตํด ๋นํจ์จ์ ์ผ๋ก ์ ๋ฌ๋๋ฉด ์ฌ์ฉ์ ๊ฒฝํ์ ์ฌ์ ํ ์ ํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๋ค์ํ ๋คํธ์ํฌ ์๋๋ฅผ ๊ฐ์ง ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ํนํ ํด๋น๋ฉ๋๋ค.
์ง์ฐ ๋ก๋ฉ(Lazy Loading)์ ํ
๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง๊ฐ ์ฒ์ ๋ก๋๋ ๋ ํ์๋ ํ์๋ ์์ต๋๋ค. ํธํฐ, ๋ชจ๋ฌ ๋๋ ์ด๊ธฐ์ ํ์ฑํ๋์ง ์์ ํญ์ ์๋ ์ปดํฌ๋ํธ๋ค์ ์ง์ฐ ๋ก๋ฉ์ ์ฃผ์ ๋์์ ๋๋ค.
์ ๋ต: ํ์ํ ๋๋ง ์ปดํฌ๋ํธ ์ ์๋ฅผ ๋ก๋ํฉ๋๋ค. IntersectionObserver
API๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ๊ฐ ๋ทฐํฌํธ์ ๋ค์ด์ค๋ ค๊ณ ํ ๋๋ฅผ ๊ฐ์งํ ๋ค์, ํด๋น ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋์ ๋์ ์ผ๋ก ๊ฐ์ ธ์ต๋๋ค.
์์: ์ง์ฐ ๋ก๋ฉ ํจํด
// In your main application script
const cardElements = document.querySelectorAll('product-card[lazy]');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// The component is near the viewport, load its code
import('./components/product-card.js');
// Stop observing this element
observer.unobserve(entry.target);
}
});
});
cardElements.forEach(card => observer.observe(card));
์ฝ๋ ์คํ๋ฆฌํ ๊ณผ ๋ฒ๋ค๋ง
์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๋ํ ์ฝ๋๋ฅผ ํฌํจํ๋ ๋จ์ผ์ ๋ชจ๋๋ฆฌ์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฒ๋ค์ ๋ง๋ค์ง ๋ง์ธ์. ์ด๋ ์ฌ์ฉ์๊ฐ ๊ฒฐ์ฝ ๋ณด์ง ์์ ์๋ ์๋ ์ปดํฌ๋ํธ์ ์ฝ๋๊น์ง ๋ค์ด๋ก๋ํ๋๋ก ๊ฐ์ํฉ๋๋ค.
์ ๋ต: ์ต์ ๋ฒ๋ค๋ฌ(Vite, Webpack, Rollup ๋ฑ)๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ๋ ผ๋ฆฌ์ ์ธ ์ฒญํฌ๋ก ์ฝ๋ ์คํ๋ฆฌํ ํ์ธ์. ํ์ด์ง๋ณ, ๊ธฐ๋ฅ๋ณ๋ก ๊ทธ๋ฃนํํ๊ฑฐ๋ ๊ฐ ์ปดํฌ๋ํธ๋ฅผ ์์ฒด ์ง์ ์ (entry point)์ผ๋ก ์ ์ํ ์๋ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ํ์ฌ ๋ทฐ์ ํ์ํ ์ฝ๋๋ง ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค.
์ค์ ์ปดํฌ๋ํธ ์ฌ์ ๋ก๋ฉ(Preloading) ๋ฐ ํ๋ฆฌํ์นญ(Prefetching)
์ฆ์ ๋ณด์ด์ง๋ ์์ง๋ง ๊ณง ํ์ํ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋์ ์ปดํฌ๋ํธ(์: ์ฌ์ฉ์๊ฐ ๋ง์ฐ์ค๋ฅผ ์ฌ๋ฆฌ๊ณ ์๋ ๋๋กญ๋ค์ด ๋ฉ๋ด์ ๋ด์ฉ)์ ๋ํด์๋ ๋ธ๋ผ์ฐ์ ์ ๋ฏธ๋ฆฌ ๋ก๋๋ฅผ ์์ํ๋ผ๋ ํํธ๋ฅผ ์ค ์ ์์ต๋๋ค.
<link rel="preload" as="script" href="/path/to/component.js">
: ํ์ฌ ํ์ด์ง์ ํ์ํ ๋ฆฌ์์ค์ ์ฌ์ฉํฉ๋๋ค. ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋๋ค.<link rel="prefetch" href="/path/to/component.js">
: ํฅํ ํ์์ ํ์ํ ์ ์๋ ๋ฆฌ์์ค์ ์ฌ์ฉํฉ๋๋ค. ๋ฎ์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋๋ค.
๊ธฐ๋ฅ 4: ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
๋ฉ๋ชจ๋ฆฌ ๋์๋ ์กฐ์ฉํ ์ฑ๋ฅ ํฌ๋ฌ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ ์ฐจ ๋๋ ค์ง๊ฒ ํ๊ณ , ํนํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ํ๋ ์ฅ์น์์๋ ๊ฒฐ๊ตญ ์ถฉ๋๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐฉ์ง
์๋ช
์ฃผ๊ธฐ ๊ธฐ๋ฅ์์ ์ธ๊ธํ๋ฏ์ด, ์น ์ปดํฌ๋ํธ์์ ๋ฉ๋ชจ๋ฆฌ ๋์์ ๊ฐ์ฅ ํํ ์์ธ์ disconnectedCallback
์์ ์ ๋ฆฌ๋ฅผ ์ ๋๋ก ํ์ง ์๋ ๊ฒ์
๋๋ค. ์ปดํฌ๋ํธ๊ฐ DOM์์ ์ ๊ฑฐ๋์์ง๋ง, ๊ทธ ์ปดํฌ๋ํธ๋ ๋ด๋ถ ๋
ธ๋ ์ค ํ๋์ ๋ํ ์ฐธ์กฐ๊ฐ ์ฌ์ ํ ๋จ์์์ ๋(์: ์ ์ญ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ์ฝ๋ฐฑ ๋ด), ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ํด๋น ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ ์ ์์ต๋๋ค. ์ด๋ฅผ "๋ถ๋ฆฌ๋ DOM ํธ๋ฆฌ(detached DOM tree)"๋ผ๊ณ ํฉ๋๋ค.
์ ๋ต: ์ ๋ฆฌ์ ์ฒ ์ ํด์ผ ํฉ๋๋ค. ์ปดํฌ๋ํธ๊ฐ ์ฐ๊ฒฐ๋ ๋ ์์ฑํ๋ ๋ชจ๋ addEventListener
, setInterval
๋๋ ๊ตฌ๋
์ ๋ํด, ์ฐ๊ฒฐ์ด ๋์ด์ง ๋ ์์ํ๋ removeEventListener
, clearInterval
๋๋ unsubscribe
ํธ์ถ์ด ์๋๋ก ๋ณด์ฅํด์ผ ํฉ๋๋ค.
ํจ์จ์ ์ธ ๋ฐ์ดํฐ ๊ด๋ฆฌ ๋ฐ ์ํ
๋ ๋๋ง์ ์ง์ ๊ด์ฌํ์ง ์๋ ํฌ๊ณ ๋ณต์กํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ปดํฌ๋ํธ ์ธ์คํด์ค์ ์ง์ ์ ์ฅํ์ง ๋ง์ธ์. ์ด๋ ์ปดํฌ๋ํธ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๋ถํ๋ฆฝ๋๋ค. ๋์ , ์ ์ฉ ์คํ ์ด๋ ์๋น์ค์์ ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ , ์ปดํฌ๋ํธ์๋ ๋ ๋๋ง์ ํ์ํ ๋ฐ์ดํฐ๋ง ํ์ํ ๋ ์ ๊ณตํ์ธ์.
๊ธฐ๋ฅ 5: ํด๋ง ๋ฐ ์ธก์
"์ธก์ ํ ์ ์๋ ๊ฒ์ ์ต์ ํํ ์ ์๋ค"๋ ์ ๋ช ํ ์ธ์ฉ๋ฌธ์ด ์ด ๊ธฐ๋ฅ์ ๊ธฐ์ด์ ๋๋ค. ์ง๊ฐ๊ณผ ๊ฐ์ ์ ํ์คํ ๋ฐ์ดํฐ๋ฅผ ๋์ฒดํ ์ ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ
๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ๋ ๊ฐ๋ฐ์ ๋๊ตฌ๋ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๋๋งน์ ๋๋ค.
- ์ฑ๋ฅ ํญ: ํ์ด์ง ๋ก๋๋ ํน์ ์ํธ์์ฉ์ ์ฑ๋ฅ ํ๋กํ์ผ์ ๊ธฐ๋กํ์ธ์. ๊ธด ์์ (ํ๋ ์ ์ฐจํธ์ ๋ ธ๋์ ๋ธ๋ก)์ ์ฐพ์ ์ปดํฌ๋ํธ์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ก ์ถ์ ํด ๋ณด์ธ์. ๋ ์ด์์ ์ค๋์ฑ(๋ฐ๋ณต๋๋ ๋ณด๋ผ์ "Layout" ๋ธ๋ก)์ ์๋ณํ์ธ์.
- ๋ฉ๋ชจ๋ฆฌ ํญ: ์ปดํฌ๋ํธ๊ฐ ํ์ด์ง์ ์ถ๊ฐ๋๊ณ ์ ๊ฑฐ๋๊ธฐ ์ ํ์ ํ ์ค๋ ์ท์ ์ฐ์ด๋ณด์ธ์. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์๋ ์ํ๋ก ๋์์ค์ง ์์ผ๋ฉด "Detached" DOM ํธ๋ฆฌ๋ฅผ ํํฐ๋งํ์ฌ ์ ์ฌ์ ์ธ ๋์๋ฅผ ์ฐพ์ผ์ธ์.
Lighthouse ๋ฐ ์ฝ์ด ์น ๋ฐ์ดํ ๋ชจ๋ํฐ๋ง
์ ๊ธฐ์ ์ผ๋ก ํ์ด์ง์์ ๊ตฌ๊ธ Lighthouse ๊ฐ์ฌ๋ฅผ ์คํํ์ธ์. ์ด๋ ๋์ ์์ค์ ์ ์์ ์คํ ๊ฐ๋ฅํ ๊ถ์ฅ ์ฌํญ์ ์ ๊ณตํฉ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ์คํ ์๊ฐ ๋จ์ถ, ๋ ๋๋ง ์ฐจ๋จ ๋ฆฌ์์ค ์ ๊ฑฐ, ์ด๋ฏธ์ง ํฌ๊ธฐ ์ ์ ํ ์กฐ์ ํ๊ธฐ์ ๊ด๋ จ๋ ๊ธฐํ์ ํนํ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ด์ธ์. ์ด ๋ชจ๋ ๊ฒ์ ์ปดํฌ๋ํธ ์ฑ๋ฅ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค.
์ค์ ์ฌ์ฉ์ ๋ชจ๋ํฐ๋ง (RUM)
์คํ์ค ๋ฐ์ดํฐ๋ ์ข์ง๋ง, ์ค์ ๋ฐ์ดํฐ๋ ๋ ์ข์ต๋๋ค. RUM ๋๊ตฌ๋ ๋ค์ํ ์ฅ์น, ๋คํธ์ํฌ ๋ฐ ์ง์ญ์ ๊ฑธ์ณ ์ค์ ์ฌ์ฉ์๋ก๋ถํฐ ์ฑ๋ฅ ์งํ๋ฅผ ์์งํฉ๋๋ค. ์ด๋ ํน์ ์กฐ๊ฑด์์๋ง ๋ํ๋๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. PerformanceObserver
API๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ปดํฌ๋ํธ๊ฐ ์ํธ์์ฉ ๊ฐ๋ฅํด์ง๊ธฐ๊น์ง ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํ๋ ์ฌ์ฉ์ ์ ์ ์งํ๋ฅผ ๋ง๋ค ์๋ ์์ต๋๋ค.
์ฌ๋ก ์ฐ๊ตฌ: ์ ํ ์นด๋ ์ปดํฌ๋ํธ ์ต์ ํ
์ฐ๋ฆฌ์ ํ๋ ์์ํฌ๋ฅผ ํํ ์ค์ ์๋๋ฆฌ์ค์ ์ ์ฉํด ๋ณด๊ฒ ์ต๋๋ค: ๋ง์ <product-card>
์น ์ปดํฌ๋ํธ๊ฐ ์๋ ์ ํ ๋ชฉ๋ก ํ์ด์ง๊ฐ ์ด๊ธฐ ๋ก๋๋ฅผ ๋๋ฆฌ๊ฒ ํ๊ณ ์คํฌ๋กค์ ๋ฒ๋ฒ
๊ฑฐ๋ฆฌ๊ฒ ๋ง๋๋ ๊ฒฝ์ฐ์
๋๋ค.
๋ฌธ์ ๊ฐ ์๋ ์ปดํฌ๋ํธ:
- ๊ณ ํด์๋ ์ ํ ์ด๋ฏธ์ง๋ฅผ ์ฆ์ ๋ก๋ํฉ๋๋ค.
- ์๋์ฐ DOM ๋ด์ ์ธ๋ผ์ธ
<style>
ํ๊ทธ์ ์คํ์ผ์ ์ ์ํฉ๋๋ค. connectedCallback
์์ ์ ์ฒด DOM ๊ตฌ์กฐ๋ฅผ ๋๊ธฐ์ ์ผ๋ก ๊ตฌ์ถํฉ๋๋ค.- ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ํฌ๊ณ ๋จ์ผํ ์ ํ๋ฆฌ์ผ์ด์ ๋ฒ๋ค์ ์ผ๋ถ์ ๋๋ค.
์ต์ ํ ์ ๋ต:
- (๊ธฐ๋ฅ 3 - ๋คํธ์ํฌ) ๋จผ์ ,
product-card.js
์ ์๋ฅผ ์์ฒด ํ์ผ๋ก ๋ถ๋ฆฌํ๊ณ , ํ๋ฉด ํ๋จ์ ์๋ ๋ชจ๋ ์นด๋์ ๋ํดIntersectionObserver
๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ฐ ๋ก๋ฉ์ ๊ตฌํํฉ๋๋ค. - (๊ธฐ๋ฅ 3 - ๋คํธ์ํฌ) ์ปดํฌ๋ํธ ๋ด๋ถ์์,
<img>
ํ๊ทธ๋ฅผ ๋ค์ดํฐ๋ธloading="lazy"
์์ฑ์ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝํ์ฌ ํ๋ฉด ๋ฐ ์ด๋ฏธ์ง์ ๋ก๋ฉ์ ์ง์ฐ์ํต๋๋ค. - (๊ธฐ๋ฅ 2 - ๋ ๋๋ง) ์ปดํฌ๋ํธ์ CSS๋ฅผ ๋จ์ผ ๊ณต์
CSSStyleSheet
๊ฐ์ฒด๋ก ๋ฆฌํฉํ ๋งํ๊ณadoptedStyleSheets
๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฉํฉ๋๋ค. ์ด๋ 100๊ฐ ์ด์์ ์นด๋์ ๋ํ ์คํ์ผ ํ์ฑ ์๊ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ํญ ์ค์ฌ์ค๋๋ค. - (๊ธฐ๋ฅ 2 - ๋ ๋๋ง) DOM ์์ฑ ๋ก์ง์ ๋ณต์ ๋
<template>
์์์ ์ฝํ ์ธ ๋ฅผ ์ฌ์ฉํ๋๋ก ๋ฆฌํฉํ ๋งํฉ๋๋ค. ์ด๋ ์ผ๋ จ์createElement
ํธ์ถ๋ณด๋ค ์ฑ๋ฅ์ด ์ข์ต๋๋ค. - (๊ธฐ๋ฅ 5 - ํด๋ง) ์ฑ๋ฅ ํ๋กํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ด์ง ๋ก๋ ์์ ๊ธด ์์ ์ด ์ค์ด๋ค๊ณ , ํ๋ ์ ๋๋กญ ์์ด ์คํฌ๋กค์ด ๋ถ๋๋ฌ์์ก๋์ง ํ์ธํฉ๋๋ค.
๊ฒฐ๊ณผ: ์ด๊ธฐ ๋ทฐํฌํธ๊ฐ ํ๋ฉด ๋ฐ ์ปดํฌ๋ํธ์ ์ด๋ฏธ์ง์ ์ํด ์ฐจ๋จ๋์ง ์์ผ๋ฏ๋ก ์ต๋ ์ฝํ ์ธ ํ ํ์ธํธ(LCP)๊ฐ ํฌ๊ฒ ๊ฐ์ ๋์์ต๋๋ค. ์ํธ์์ฉ๊น์ง์ ์๊ฐ(TTI)์ด ํฅ์๋๊ณ ์คํฌ๋กค ๊ฒฝํ์ด ๋ถ๋๋ฌ์์ ธ, ๋ชจ๋ ๊ณณ์ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ํจ์ฌ ๊ฐ์ ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
๊ฒฐ๋ก : ์ฑ๋ฅ ์ฐ์ ๋ฌธํ ๊ตฌ์ถํ๊ธฐ
์น ์ปดํฌ๋ํธ ์ฑ๋ฅ์ ํ๋ก์ ํธ ๋ง๋ฐ์ง์ ์ถ๊ฐํ๋ ๊ธฐ๋ฅ์ด ์๋๋๋ค. ๊ฐ๋ฐ ์๋ช ์ฃผ๊ธฐ ์ ๋ฐ์ ๊ฑธ์ณ ํตํฉ๋์ด์ผ ํ๋ ๊ธฐ๋ณธ ์์น์ ๋๋ค. ์ฌ๊ธฐ์ ์ ์๋ ํ๋ ์์ํฌโ์๋ช ์ฃผ๊ธฐ, ๋ ๋๋ง, ๋คํธ์ํฌ, ๋ฉ๋ชจ๋ฆฌ, ํด๋ง์ ๋ค์ฏ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ด์ ์ ๋ง์ถโ๋ ๊ณ ์ฑ๋ฅ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ฐ๋ณต ๊ฐ๋ฅํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ๋ก ์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฌํ ์ฌ๊ณ ๋ฐฉ์์ ์ฑํํ๋ ๊ฒ์ ํจ์จ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ ์ด์์ ์๋ฏธํฉ๋๋ค. ์ฑ๋ฅ ์์ฐ์ ์ค์ ํ๊ณ , ์ง์์ ์ธ ํตํฉ(CI) ํ์ดํ๋ผ์ธ์ ์ฑ๋ฅ ๋ถ์์ ํตํฉํ๋ฉฐ, ๋ชจ๋ ๊ฐ๋ฐ์๊ฐ ์ต์ข ์ฌ์ฉ์ ๊ฒฝํ์ ๋ํด ์ฑ ์๊ฐ์ ๋๋ผ๋ ๋ฌธํ๋ฅผ ์กฐ์ฑํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํจ์ผ๋ก์จ, ์ฐ๋ฆฌ๋ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํด ๋ ๋น ๋ฅด๊ณ , ๋ ๋ชจ๋ํ๋๊ณ , ๋ ์ฆ๊ฑฐ์ด ์น์ ๊ตฌ์ถํ๋ค๋ ์น ์ปดํฌ๋ํธ์ ์ฝ์์ ์ง์ ์ผ๋ก ์คํํ ์ ์์ต๋๋ค.