"์ฐ๋ฆฌ ์น์ฌ์ดํธ๋ ์์๊ณ ๊ธฐ๋ฅ๋ ์ข์๋ฐ... ์ ์ด๋ ๊ฒ ๋๋ฆฌ์ง?"
โ ๋ชจ๋ ๊ฐ๋ฐ์์ ๊ณ ๋ฏผ
์ด ๊ธ์ ๋๋ํ ์ฌ๋๋ง ๋ณด๋ ์ด๋ ต๊ณ ๋ณต์กํ ์ต์ ํ๊ฐ ์๋๋ผ, ๋ฐ๋ก ์ง๊ธ ๋น์ฅ ์ ์ฉ ๊ฐ๋ฅํ ์ฌ์ด ํ์ ์๋ ค์ฃผ๋ ๊ธ์ด์ผ. ํจ๊ป ๋ฐ๋ผ ํ๋ฉด์ ์ฌ๋ฌ๋ถ์ ์น์ฌ์ดํธ๋ฅผ ๋ ์๊ฐ๊ฒ ๋ง๋ค์ด๋ณผ๊น? โ๏ธโจ
์น์ฌ์ดํธ๊ฐ ๋๋ฆฐ ๊ฐ์ฅ ํฐ ์ด์ ์ค ํ๋๋ ๋ฐ๋ก ์ด๋ฏธ์ง์ผ.
์์๊ฒ ๋ณด์ด๋ ค๊ณ ์ฌ๋ฆฐ ์ด๋ฏธ์ง๊ฐ ๋๋ฌด ์ปค์ ๋ก๋ฉ์ด ๋๋ฆฌ๋ค๋ฉด?
์ฌ์ฉ์๋ ๋ค๊ฐ ์ด์ฌํ ๋ง๋ ํ์ด์ง๋ฅผ ๋ณด์ง๋ ์๊ณ ๋ ๋๋ฒ๋ฆด๊ฑธ? ๐ญ
โ
์ด๋ฏธ์ง ํฌ๊ธฐ ์ค์ด๊ธฐ
PNG โ JPG or WebP๋ก ๋ณํํ๋ฉด ์ด๋ฏธ์ง๋ง์ผ๋ก ์๋๊ฐ ์ต๋ 50% ํฅ์๋ ์ ์์ด!
(WebP๋ฅผ ๋ชฐ๋๋ค๊ณ ? ๊ฑฑ์ ๋ง, ๋ธ๋ผ์ฐ์ ์ง์๋ ๊ฑฐ์ ๋ค ๋ผ! ๐)
โ
์ด๋ฏธ์ง ์์ถํ๊ธฐ
TinyPNG๋ Compressor.io์์ ์ด๋ฏธ์ง ํ์ผ์ ๋์ด๋ค๊ฐ ๋์ ธ๋์ผ๋ฉด ๋์ด์ผ! (๋ช ์ด๋ง์ ์์ถ ์๋ฃ!)
<!-- ๋ฐ๊พธ๊ธฐ ์ -->
<img src="huge-image.png">
<!-- ๋ฐ๊พผ ํ -->
<img src="compressed-image.webp">
"์์ด~ ์ด๋ฏธ์ง ์์ถํ๋ค๊ณ ์ผ๋ง๋ ๋นจ๋ผ์ง๊ฒ ์ด?"
์ง์ ํด๋ด, ๋ฐ๋ก ์ฒด๊ฐ๋ ๊ฑธ? ๐
CDN(Content Delivery Network)์ด๋ ์ฝ๊ฒ ๋งํด์,
์ ์ธ๊ณ ๊ณณ๊ณณ์ ์น์ฌ์ดํธ ํ์ผ์ ๋ณต์ฌํด ๋๊ณ ,
๊ฐ์ฅ ๊ฐ๊น์ด ์์น์์ ๋น ๋ฅด๊ฒ ์ ๋ฌํด์ฃผ๋ ๋ง๋ฒ ๊ฐ์ ์๋น์ค์ผ!
๊ฐ์ฅ ์ฝ๊ฒ ์ฐ๋ ๋ฐฉ๋ฒ์?
Cloudflare ๊ฐ์ ๋ฌด๋ฃ CDN์ ์จ์ ๋ฒํผ ๋ช ๋ฒ ํด๋ฆญ์ผ๋ก ์ ์ฉ ๋!
"CDN์ด ๋ญ ์ผ๋ง๋ ๋นจ๋ผ์ง๊น?" ํ๊ณ ์์ฌํ์ง ๋ง๊ณ ์จ๋ด!
๊ฑฐ์ง๋ง ์ ํ๊ณ , ์ฒด๊ฐ ์๋๊ฐ ๋ ๋ฐฐ๋ ๋นจ๋ผ์ง ๊ฑฐ์ผ. ๐ฑ
๋๋ ๋ชจ๋ฅด๋ ์ ์น์ฌ์ดํธ๊ฐ ๋๋ ค์ง ์ด์ ๋ ๋ฐ๋ก,
์๋ง์ JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ ์๋ ์ฝ๋ ๋๋ฌธ์ด์ผ!
โ ๋ฒ๋ค ์ต์ ํ (Webpack ๊ธฐ์ค)
// Webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all', // ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฐ๋ก ๋ถ๋ฆฌ!
},
},
};
โ
๋ถํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ญ์ ํ๊ธฐ
moment.js๊ฐ ์ฉ๋ ํฌ๊ธฐ๋ก ์
๋ช
๋์ ๊ฑฐ ์์ง?
(๋์ฒด์ฌ๋ก dayjs ๊ฐ์ ๊ฐ๋ฒผ์ด ๊ฑธ ์จ๋ณด์)
โ
Tree Shaking ํ์ฑํ
์ฌ์ฉํ์ง ์๋ ์ฝ๋ ์ ๊ฑฐ!
{
"sideEffects": false
}
(package.json์ ์ถ๊ฐ!)
์ด ์ ๋๋ง ์ ์ฉํด๋ ์ต์ JS ๋ฒ๋ค ์ฉ๋์ด 30~50% ์ค์ด๋ค ๊ฑฐ์ผ! ๐
์ฌ์ฉ์๊ฐ ํ ๋ฒ์ด๋ผ๋ ๋ฐฉ๋ฌธํ๋ค๋ฉด ์ด๋ฏธ ๋ด๋ ค๋ฐ์ ์ฝํ
์ธ ๋ ๋ค์ ๋ค์ด๋ก๋ํ ํ์๊ฐ ์์์?
๋ธ๋ผ์ฐ์ ์๊ฒ "์บ์ํด๋ ๋ผ!"๋ผ๊ณ ์๋ ค์ฃผ์.
.htaccess๋ ์๋ฒ ์ค์ ์์ ๊ฐ๋จํ ์ค์ ๊ฐ๋ฅ!
# .htaccess (Apache ์๋ฒ)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/jpeg "access plus 6 months"
</IfModule>
ํ ์ค๋ก ์๋ฒ๊ฐ ์์ฒญ๋๊ฒ ๋นจ๋ผ์ง๋ ๋ง๋ฒ ๊ฐ์ ๋ณํ! ๐ฅ
ํ์ด์ง๋ฅผ ์ฒ์๋ถํฐ ๋ชจ๋ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ฉํ๋ฉด ์ค๋ ๊ฑธ๋ฆฌ์ง?
๊ทธ๋ผ, ์คํฌ๋กคํ ๋๋ง ์ด๋ฏธ์ง๋ฅผ ๋ก๋ฉํ๊ฒ ๋ง๋ค๋ฉด ์ด๋?
HTML๋ง์ผ๋ก๋ ๊ฐ๋ฅํด!
<img src="image.jpg" loading="lazy">
๋ธ๋ผ์ฐ์ ๊ฐ ์๋์ผ๋ก ์์์ ์ฒ๋ฆฌํด์ค ๊ฑฐ์ผ.
์ด๊ฒ๋ง ์ ์ฉํด๋ ์ฒด๊ฐ ๋ก๋ฉ ์๋๊ฐ ์์ฒญ ๋นจ๋ผ์ ธ! ๐
๊ฐ๋ฐ์๋ค์ด ์ต์ ํ๋ฅผ ์ธ๋ฉดํ๋ ์ด์ ๋ ๋จ ํ๋์ผ.
"๋ญ๋ถํฐ ํด์ผ ํ ์ง ๋ชฐ๋ผ์..."
๊ทธ๋์ ์ฌ๊ธฐ ์๋ ํ๋ถํฐ ํ๋์ฉ ๋ฐ๋ผ ํด๋ด.
์ ๋ง๋ก ๋๋๊ฒ ํ์ด์ง๊ฐ ๋นจ๋ผ์ง๋ ๊ฑธ ๋๋ ์ ์์ ๊ฑฐ์ผ.
์ต์ ํ๋ ์ด๋ ต์ง ์์!
์์ ๋
ธ๋ ฅ์ผ๋ก ํฐ ๋ณํ๋ฅผ ๋ง๋ค์ด๋ณด์๊ณ ! ๐ช๐ฅ
์ด ์ค์ ํ๋๋ง ์ ์ฉํด๋ ๋๋ ์ ์๋ ๋ณํ๊ฐ ๋ํ๋ ๊ฑฐ์ผ.
์ด์ ๋์ ์น์ฌ์ดํธ๋...
โจ โ๊ด์ ๋ก๋ฉโ โจ์ ํฅํด ๊ฐ๋ค!!!
(์ข์์ ๋๋ฅด๋ฉด ํ์ด์ 10๋ฐฐ ์ฑ๋ฅ ํฅ์์ด ์ฌ์ง๋?! ๐)
์ด๋? ์ฌ๋ฐ๊ณ ์ฝ๊ฒ ์ฝ์ ์ ์๊ฒ ์ถฉ๋ถํ ํ์ด๋จ๋๋ฐ,
ํน์ ๋ ๊ตฌ์ฒด์ ์ธ ์์๋ ๊ถ๊ธํ ๋ถ๋ถ ์์ผ๋ฉด ์ธ์ ๋ ๋งํด์ค!
์, ์์ฒญ๋๊ฒ ์ฌ๋ฏธ์๊ณ ์ ์ตํ ๊ธ์ด์์ต๋๋ค. ๊ณ ๋ง์ต๋๋ค.
์ข์ ๋ด์ฉ์ด๋ค์. ํนํ ์ต๊ทผ์ ๊ฒฝํํ ๋ด์ฉ๋ ํฌํจ๋์ด ์์ด ํฅ๋ฏธ์๊ฒ ์ฝ์์ต๋๋ค. CDN์ ๊ฒฝ์ฐ ์ ๊ฐ ์ฐธ์ฌํ ๋ชจ๋ฐ์ผ๋ถ์ผ์์๋ ํ์ฉ์ด ๋์๊ฑฐ๋ ์.
์๋ฅผ๋ค์ด ์ฅ์ ๋ฐ์๋ฑ์ผ๋ก ๋๊ท๋ชจ ํธ๋ํฝ์ด ๋ฐ์ํ ๊ฒฝ์ฐ CDN์ ์ด์ฉํ์ฌ ์ ์ ํ ์๋ต์ JSONํ์ผ(์ ์ ํ์ผ)๋ก ๋ฐฐ์นํด ์ฒ๋ฆฌํ์ด์.
์ข์๊ธ ์๋ดค์ต๋๋ค! ํฌ์คํธ์ ์๋ ์ด๋ฏธ์ง๋ ์ด๋ค ํด๋ก ๊ทธ๋ฆฌ์ ๊ฑธ๊ฐ์?
์๊ฐํ๊ฐ ์๋์ด์ ๊ธ์ ์ดํดํ๋๋ฐ ์ข๋๋ผ๊ณ ์!