๐Ÿš€ ํ”„๋ก ํŠธ์—”๋“œ ์„ฑ๋Šฅ ๊ฐœ์„ ํ•˜๊ธฐ -๋กœ๋”ฉ-

thumb_hyeokยท2022๋…„ 9์›” 6์ผ
18

๐Ÿ”ฅ WoowaCourse

๋ชฉ๋ก ๋ณด๊ธฐ
3/10

๐Ÿค” ์„ฑ๋Šฅ ๊ฐœ์„ ์„ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๋‚ด๊ฐ€ ์‚ฌ์šฉ์ž๋ผ๋„ ๋Š๋ คํ„ฐ์ง„ ์›น์‚ฌ์ดํŠธ์—๋Š” ๋‹ค์‹œ ์ ‘์†ํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค. ๋งŒ์•ฝ ์›น์‚ฌ์ดํŠธ๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ถˆํŽธํ•จ์„ ๋Š๋‚„ ์ •๋„๋กœ ํผํฌ๋จผ์Šค์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด ์›น์‚ฌ์ดํŠธ์˜ ์„ฑ๋Šฅ๊ฐœ์„ ์ด ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.
์•„๋ž˜์—์„œ ์–ด๋–ป๊ฒŒ ์›น์‚ฌ์ดํŠธ์˜ ์„ฑ๋Šฅ๊ฐœ์„ ์„ ํ•  ์ˆ˜ ์žˆ์„์ง€ ์•Œ์•„๋ณด์ž.


๐Ÿงพ ์ธก์ •, ๋ถ„์„

๋จผ์ € ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋Š๋ฆฌ๋‹ค๋ฉด ์™œ ๋Š๋ฆฐ์ง€ ๋ฌธ์ œ๋ฅผ ๋จผ์ € ํŒŒ์•…ํ•˜๊ณ , ๊ทธ ๋ฌธ์ œ์— ๋งž๋Š” ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•„์•ผํ•˜๊ธฐ๋•Œ๋ฌธ์— "์ธก์ •"์„ ํ•˜๋Š” ๊ณผ์ •์ด ์ค‘์š”ํ•œ๋‹ค. chrome ๋ธŒ๋ผ์šฐ์ €์˜ Lighthouse๋‚˜ WebPageTest๋ฅผ ํ†ตํ•ด ์›น์‚ฌ์ดํŠธ์˜ ์†๋„๊ฐ€ ๋Š๋ฆฐ ์ด์œ ๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ์‹œ๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹์œผ๋‹ˆ, Lighthouse๋ฅผ ํ†ตํ•ด ํŒ€ ํ”„๋กœ์ ํŠธ์˜ ์„ฑ๋Šฅ ๋ถ„์„ ๋ฆฌํฌํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

์ด๋Ÿฐ์‹์œผ๋กœ ์„ฑ๋Šฅ ๋ถ„์„ ๋ฆฌํฌํŠธ๋ฅผ ํ†ตํ•ด ์›น์‚ฌ์ดํŠธ์˜ ์†๋„๊ฐ€ ๋Š๋ฆฐ ์ด์œ ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๊ณ , ์ด๋ฅผ ํ† ๋Œ€๋กœ ์–ด๋–ป๊ฒŒ ์›น์‚ฌ์ดํŠธ์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚ด๊ฐ€ ํŒŒ์•…ํ•œ ๋ฌธ์ œ์ ๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™์•˜๋‹ค.

  • ์š”์†Œ ํฌ๊ธฐ์— ๋น„ํ•ด ๋„ˆ๋ฌด ํฐ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉ์ค‘์ด๋‹ค.
  • ์šฉ๋Ÿ‰์ด ์ž‘์€ ์ฐจ์„ธ๋Œ€ ํŒŒ์ผ ํ˜•์‹ (webp ๋“ฑ๋“ฑ)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค.
  • ๋ฒˆ๋“คํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฌ๋‹ค.
  • ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๊ฐ€ ๋ฒˆ๋“คํŒŒ์ผ์— ํฌํ•จ๋˜์—ˆ๋‹ค.
  • ์บ์‹œ ์ •์ฑ…์ด ํšจ์œจ์ ์ด์ง€ ์•Š๋‹ค.
  • ๋„คํŠธ์›Œํฌ ํŽ˜์ด๋กœ๋“œ๊ฐ€ ๋„ˆ๋ฌด ํฌ๋‹ค. (์š”์ฒญ ์ˆ˜๋„ ๋งŽ๊ณ , ์š”์ฒญ ํฌ๊ธฐ๋„ ํฌ๋‹ค)

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ทธ๋ฆฌ๊ณ  ๋” ์ƒ์„ธํ•œ ๋ถ„์„์€, ์ด๋ฒˆ ๊ธ€ ํ”„๋ก ํŠธ์—”๋“œ ์„ฑ๋Šฅ ๊ฐœ์„ ํ•˜๊ธฐ (๋กœ๋”ฉ)๊ณผ ๋‹ค์Œ ๊ธ€์ธ ๋ Œ๋”๋งํŽธ์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.


๐Ÿ–ผ๏ธ ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ค„์ด๊ธฐ

๊ฐ€์žฅ ๋จผ์ € ์†๋ด์•ผํ•  ๋ถ€๋ถ„์€ "์ด๋ฏธ์ง€"์ด๋‹ค. ์•„๋ž˜ ์‚ฌ์ง„์€ ์›น์‚ฌ์ดํŠธ์— ์ ‘์†ํ•˜๋ฉด ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค์ธ๋ฐ, ์ด๋ฏธ์ง€๊ฐ€ ๋ฌด๋Ÿฌ 6MB๋ฅผ ๋„˜๋Š” ์ˆ˜์ค€์œผ๋กœ ์••๋„์ ์ธ ์šฉ๋Ÿ‰์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋‹ค. ํŒŒ์ผํ˜•์‹์˜ ๋ณ€๊ฒฝ๊ณผ ์••์ถ•์ด ์‚ฌ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

format, compresstion

๊ฐ€์žฅ ๋จผ์ € png, gif ์ฒ˜๋Ÿผ ์šฉ๋Ÿ‰์ด ํฐ ํŒŒ์ผํ˜•์‹์„ webp,mp4 ๋“ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. webpack ์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ™œ์šฉํ•ด์„œ ๋ฒˆ๋“ค ์‹œ์— ์—ฌ๋Ÿฌ ์„ค์ •์„ ํ†ตํ•ด ์šฉ๋Ÿ‰์„ ์ค„์ด๊ฑฐ๋‚˜, ํ˜•์‹์„ ๋ฐ”๊ฟ”์ค„ ์ˆ˜๋„ ์žˆ๊ณ , ์ง์ ‘ sqoose ๊ฐ™์€ ์—ฌ๋Ÿฌ ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์ •๋ง ๋งŽ๊ณ  ํ•˜๋‚˜์˜ ์ •๋‹ต๋ณด๋‹ค๋Š” ์ƒํ™ฉ์— ๋งž๊ฒŒ ํ•˜๋Š”๊ฒŒ ๋งž๋Š” ๊ฒƒ ๊ฐ™์•„ ๊ฐ„๋‹จํžˆ ์†Œ๊ฐœ๋งŒ ํ•˜๊ฒ ๋‹ค!


๐Ÿ“ฆ ์†Œ์Šค์ฝ”๋“œ ํฌ๊ธฐ ์ค„์ด๊ธฐ

๋‹ค์Œ์— ์‚ดํŽด๋ณผ ๋‚ด์šฉ์€ ์†Œ์Šค์ฝ”๋“œ์ด๋‹ค. ์—ฌ๊ธฐ์„œ ์›นํŒฉ์ด ๋ฒˆ๋“ค๋งํ•œ main.xxx.js ํŒŒ์ผ์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋ฌด๋ ค 1.7MB ์ˆ˜์ค€์œผ๋กœ ์ด ๋ฒˆ๋“คํŒŒ์ผ์ด ์‘๋‹ต์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ ์›น์‚ฌ์ดํŠธ๋Š” ํฐ ๋ฐฐ๊ฒฝ๋งŒ ๋ณด์ผ ๋ฟ์ด๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ๋‹น์—ฐํžˆ ์ข‹์ง€ ์•Š์„ ์ˆ˜ ๋ฐ–์— ์—†์œผ๋ฏ€๋กœ ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ์ค„์—ฌ๋ณด์ž!

CSS, JS minify, uglify

minify(์••์ถ•)์€ ์ฝ”๋“œ์˜ ๋ถˆํ•„์š”ํ•œ ์ค„๋ฐ”๊ฟˆ, ๊ณต๋ฐฑ ๋ฐ‘ ๋“ค์—ฌ์“ฐ๊ธฐ, ์งง๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ธด ๊ตฌ๋ฌธ ๋“ฑ๋“ฑ์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜์—ฌ ์†Œ์Šค ์ฝ”๋“œ์˜ ํŒŒ์ผ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
๊ทธuglify(๋‚œ๋…ํ™”)๋Š” ์ฝ”๋“œ๋ฅผ ์ฝ๊ธฐ ํž˜๋“ค๊ฒŒ ๋งŒ๋“œ๋Š” ๊ณผ์ •์ด๋‹ค. ๋ณ€์ˆ˜๋ช…, ํ•จ์ˆ˜๋ช…๋“ค์ด ์งง์•„์ ธ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋‚˜, ๋‚œ๋…ํ™” ์ˆ˜์ค€์ด ๋†’์•„์งˆ์ˆ˜๋ก ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

bundle.js ํŒŒ์ผ์€ webpack5 ๊ธฐ์ค€์œผ๋กœ minify, uglify๊ฐ€ TerserPlugin ์ด ๋‚ด์žฅ ๋˜์–ด production ๋ชจ๋“œ์—์„œ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ์ตœ์ ํ™”๊ฐ€ ์ง„ํ–‰๋œ๋‹ค. webpack5๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๊ธฐ์— ์ด ๊ณผ์ •์€ ์ƒ๋žตํ–ˆ๋‹ค.

๋˜ํ•œ CSS-in-JS๋Š” babel ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง ๊ณผ์ •์—์„œ ์ตœ์ ํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์— CSS-in-CSS์ธ ๊ฒฝ์šฐ์—๋งŒ ์••์ถ•ํ™” ๋‚œ๋…ํ™”๋ฅผ ์ ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ํ”„๋กœ์ ํŠธ์—์„œ styled-component๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋˜ํ•œ ์ƒ๋žตํ–ˆ๋‹ค.!

์••์ถ•์„ ์ง„ํ–‰ํ•˜๋ฉด, ์™ผ์ชฝ์˜ ๋ฒˆ๋“คํŒŒ์ผ์ด ์˜ค๋ฅธ์ชฝ๊ณผ ๊ฐ™์ด ๋ณ€ํ•œ๋‹ค. (๋‚œ๋…ํ™”๋Š” ์™ผ์ชฝ๋„ ์ง„ํ–‰๋œ ์ƒํƒœ์ด๋‹ค.)

์˜ค์ง ์••์ถ• ํ•˜๋‚˜๋งŒ์œผ๋กœ ์ด์ •๋„์˜ ํŒŒ์ผ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋‹ˆ, ๊ผญ ์••์ถ•๊ณผ ๋‚œ๋…ํ™”๋ฅผ ์ ์šฉํ•ด๋ณด์ž!


gzip

gzip ์€ ํŒŒ์ผ ์••์ถ•์— ์“ฐ์ด๋Š” ์†Œํ”„ํŠธ์›จ์–ด์ด๋ฉฐ, ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์••์ถ•ํ•˜๋Š”๋ฐ์— ๋›ฐ์–ด๋‚œ ์„ฑ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €๋Š” gzip์œผ๋กœ ์••์ถ•๋œ gz ํ™•์žฅ์ž์˜ ํŒŒ์ผ์„ ์••์ถ•ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ, ์••์ถ•ํ”„๋กœ๊ทธ๋žจ์„ ์ด๋ฏธ ๋‚ด์žฅํ•˜๊ณ ์žˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ๋ฒˆ๋“คํŒŒ์ผ์„ gzip์„ ํ†ตํ•ด ์••์ถ•ํ•ด์„œ ์†Œ์Šค์ฝ”๋“œ์˜ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค!

๋จผ์ € gzip์œผ๋กœ ์••์ถ•๋œ ๋ฒˆ๋“คํŒŒ์ผ์ด ํ•„์š”ํ•˜๋‹ค! CompressionWebpackPlugin์„ ํ†ตํ•ด ๋นŒ๋“œํ•  ๋•Œ ๋ฒˆ๋“คํŒŒ์ผ์„ ์••์ถ•ํ•œ gz ํ™•์žฅ์ž์˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

// webpack.config.js

module.exports = {
  // ...
  plugins: [
    new CompressionPlugin({
      algorithm: 'gzip',
      exclude: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif|webp|txt|map|ico)$/i
    }),
  ],
  // ...
};

์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •์„ ํ•ด์ฃผ๋ฉด, ์ œ์™ธ๋œ ํŒŒ์ผ ํ˜•์‹ ์ด์™ธ์˜ ๋ฒˆ๋“คํŒŒ์ผ๋“ค์ด gzํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ์ƒ์„ฑ๋œ๋‹ค. ์•„๋ž˜ ์‚ฌ์ง„์„ ๋ณด๋ฉด gzip์••์ถ•์œผ๋กœ ๋ฒˆ๋“คํŒŒ์ผ์˜ ์šฉ๋Ÿ‰์„ ๋Œ€ํญ ์ค„์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์•„์ง ๋๋‚œ ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ์„œ๋ฒ„์™€ ๋ธŒ๋ผ์šฐ์ €๊ฐ„์˜ ์••์ถ•๋œ ํŒŒ์ผ์„ ๋ณด๋‚ด๋„ ๊ดœ์ฐฎ๋‹ค๋Š” ์„ค์ •์„ ํ•ด์ฃผ์–ด์•ผ gzipํŒŒ์ผ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์••์ถ•๋œ ์ฝ˜ํ…์ธ ๋ฅผ ์ˆ˜๋ฝํ•œ๋‹ค๋Š” Accept-Encoding: gzip ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•œ ์š”์ฒญ์„ ์„œ๋ฒ„์— ๋ณด๋‚ธ๋‹ค.

  2. ์„œ๋ฒ„๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ์š”์ฒญ์„ ๋ฐ›์€ ํ›„ ํŒŒ์ผ์„ ์ฐพ๊ณ , ์••์ถ•๋œ ํŒŒ์ผ์ด ์กด์žฌํ•  ๊ฒฝ์šฐ, Content-Encoding: gzip๋ฅผ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์‘๋‹ต์„ ๋ณด๋‚ธ๋‹ค.

  3. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์••์ถ•๋œ ํŒŒ์ผ์˜ ์••์ถ•์„ ํ•ด์ฒดํ•˜๊ณ , ํŽ˜์ด์ง€๋ฅผ ๊ทธ๋ฆฐ๋‹ค.

์œ„์™€ ๊ฐ™์€ ๊ณผ์ •์„ ํ†ตํ•ด ์••์ถ•๋œ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค!


๐Ÿ—ƒ๏ธ ํ•„์š”ํ•œ ๊ฒƒ๋งŒ ์š”์ฒญํ•˜๊ธฐ

์ด๋ ‡๊ฒŒ ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๋„, ์†Œ์Šค์ฝ”๋“œ์˜ ํฌ๊ธฐ๋„ ์ค„์—ฌ๋ดค์ง€๋งŒ, ์ง€๊ธˆ ์›นํŒฉ์€ ๋ฒˆ๋“คํŒŒ์ผ์„ ๋‹จ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š” ์—†๋Š” ์ฝ”๋“œ๋“ค์ด ๋ฒˆ๋“คํŒŒ์ผ์— ๋“ค์–ด๊ฐ€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
์ด๋Ÿฌํ•œ ์ด์œ ๋กœ AํŽ˜์ด์ง€์—์„œ ํ•„์š”ํ•œ ์ฝ”๋“œ๋งŒ์œผ๋กœ ๋ฒˆ๋“คํŒŒ์ผ ํ•˜๋‚˜, BํŽ˜์ด์ง€์—์„œ ํ•„์š”ํ•œ ์ฝ”๋“œ๋งŒ์œผ๋กœ ๋ฒˆ๋“คํŒŒ์ผ ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ๊ฐ์„ ํ•„์š”ํ•  ๋•Œ ์š”์ฒญํ•˜๋ฉด ๋” ์‘๋‹ต์˜ ํฌ๊ธฐ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“ˆ์˜ ์ผ๋ถ€๋งŒ ์‚ฌ์šฉํ•จ์—๋„ ๋ชจ๋“ˆ ์ „์ฒด๋ฅผ ๋ฒˆ๋“คํŒŒ์ผ์— ํฌํ•จํ•˜๋Š” ๋ฌธ์ œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
์•„๋ž˜์—์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž!

Code Splitting

Code Splitting์ด๋ž€ ์›นํŒฉ์„ ํ†ตํ•ด ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์ด ํ•˜๋‚˜์ผ ๊ฒฝ์šฐ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“ˆ๋“ค๊นŒ์ง€ ๋“ค์–ด๊ฐ€ ํŒŒ์ผ์ด ์ปค์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์ด ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋„๋ก ๋‚˜๋ˆ„๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋จผ์ € webpack-bundle-analyzer๋ฅผ ํ†ตํ•ด ํ˜„์žฌ์˜ ๋ฒˆ๋“คํŒŒ์ผ์„ ๋ถ„์„ํ•ด๋ณด์ž.
ํ•˜๋‚˜์˜ ๋ฒˆ๋“คํŒŒ์ผ์— ๋ชจ๋“  ํŒŒ์ผ์ด ๋“ค์–ด๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์žฅ ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ ๋ถˆํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

Code Splitting ํ•ด๋‹น ๋งํฌ์—์„œ ๋ณด๋ฉด ์ˆ˜๋งŽ์€ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ… ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๋Š” react๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, react์—์„œ ์ œ๊ณตํ•˜๋Š” Suspense, lazy๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์„ ์ ์šฉํ–ˆ๋‹ค.

// webpack.config.js

module.exports = {
  // ...
  output: {
    filename: '[name].[contenthash].bundle.js',
    path: path.join(__dirname, '/dist'),
    clean: true
  },
  // ...
};

์œ„์˜ webpack ์„ค์ •๊นŒ์ง€ ์™„๋ฃŒํ•˜๊ณ  ๋‹ค์‹œ webpack-bundle-analyzer๋ฅผ ํ†ตํ•ด ๋ฒˆ๋“ค ํŒŒ์ผ์„ ํ™•์ธํ•ด๋ณด๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ๊ฐ์˜ ๋ผ์šฐํŒ…์—์„œ ํ•„์š”ํ•œ ์ฝ”๋“œ๋“ค์ด ๋ถ„๋ฆฌ๋˜์–ด ๋ฒˆ๋“คํŒŒ์ผ๋“ค์„ ์ƒ์„ฑํ–ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


Tree Shaking

Tree Shaking ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋“ค์„ ์ œ๊ฑฐํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ESM ์˜ import, export ๋ฌธ์„ ์‚ฌ์šฉํ•ด์•ผํ•จ์œผ๋กœ, babel ์ด๋‚˜ ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์ด CommonJS ๊ฐ™์€ ๋‹ค๋ฅธ ๋ชจ๋“ˆ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ๋Š” ์ž๋™์œผ๋กœ Tree Shaking์„ ํ•ด์ฃผ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค๊ณ  ํ•˜๋‹ˆ, ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฝ์–ด๋ณด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Tree Shaking์„ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” babel์ด ๋ชจ๋“ˆ์„ ESM์œผ๋กœ ์œ ์ง€ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ค˜์•ผํ–ˆ๋‹ค.

ํ•ด๋‹น ์„ค์ •์ด ๋๋‚˜๊ณ ๋Š” ํ”„๋กœ์ ํŠธ์˜ ์–ด๋–ค ํŒŒ์ผ์ด "์ˆœ์ˆ˜"ํ•œ์ง€ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ œ๊ฑฐํ•ด๋„ ๊ดœ์ฐฎ์€์ง€๋ฅผ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด package.json์— "sideEffect" ์†์„ฑ์„ ์ž‘์„ฑํ•œ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด ์ด๊ณณ์— ํฌํ•จ๋œ ์ฝ”๋“œ๋Š” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ํฌํ•จํ•จ์„ ์•Œ๋ฆฌ๊ณ , ์ด์™ธ์˜ ํŒŒ์ผ๋“ค์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” export๋Š” ์ œ๊ฑฐํ•ด๋„ ๊ดœ์ฐฎ๋‹ค๋Š” ๊ฒƒ์„ webpack์— ์•Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ์ด์ œ ํŽ˜์ด์ง€๋ฅผ ๋กœ๋“œํ•  ๋•Œ, ํ•„์š”์—†๋Š” ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ๊นŒ์ง€ ์‚ฌ๋ผ์ง„๋‹ค!


โ™ป๏ธ ๊ฐ™์€ ๊ฑด ๋งค๋ฒˆ ์ƒˆ๋กœ ์š”์ฒญํ•˜์ง€ ์•Š๊ธฐ

์บ์‹ฑ(caching)์€ ์ฃผ์–ด์ง„ ๋ฆฌ์†Œ์Šค์˜ ๋ณต์‚ฌ๋ณธ์„ ์ €์žฅํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ์š”์ฒญ ์‹œ์— ๊ทธ๊ฒƒ์„ ์ œ๊ณตํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค. ์›น ์บ์‹œ๊ฐ€ ์ž์‹ ์˜ ์ €์žฅ์†Œ ๋‚ด์— ์š”์ฒญ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„ ์›๋ž˜์˜ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‹ค์‹œ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ๋Œ€์‹  ๋ฆฌ์†Œ์Šค์˜ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋งค๋ฒˆ ๊ฐ™์€ ํŽ˜์ด์ง€๋ฅผ ๋“ค๋ฝ๋‚ ๋ฝํ•˜๊ฒŒ๋˜๋Š”๋ฐ, ๊ทธ ๋•Œ๋งˆ๋‹ค ๊ณ„์† ์š”์ฒญ์„ ๋ณด๋‚ด ์ƒˆ๋กœ์šด ํŒŒ์ผ์„ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ์บ์‹œ์ €์žฅ์†Œ์— ๋ฆฌ์†Œ์Šค๋ฅผ ์ €์žฅํ•ด๋‘๊ณ , ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ  ์‚ฌ๋ณธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋‚˜์„ ๊ฒƒ ๊ฐ™๋‹ค.
๊ทธ ์ „์—, ์บ์‹œ์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํžˆ ์ข€ ์•Œ์•„๋ณด์ž.

์บ์‹œ์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”๋ฐ ํฌ๊ฒŒ ์‚ฌ์„ค(private), ๊ณต์œ (shared) ์บ์‹œ ๋‘ ๊ฐ€์ง€๋กœ ๋ถ„๋ฅ˜๋œ๋‹ค.
๊ณต์œ (shared) ์บ์‹œ๋Š” ํ•œ ๋ช… ์ด์ƒ์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์‘๋‹ต์„ ์ €์žฅํ•˜๋Š” ์บ์‹œ์ด๊ณ , ์‚ฌ์„ค(private) ์บ์‹œ๋Š” ํ•œ ๋ช…์˜ ์‚ฌ์šฉ์ž๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ์ด๋‹ค.

์บ์‹œ๋Š” ๋ธŒ๋ผ์šฐ์ € ์บ์‹œ, ํ”„๋ก์‹œ ์บ์‹œ, ๊ฒŒ์ดํŠธ์›จ์ด ์บ์‹œ , CDN , ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ ๋“ฑ์ด ๋งŽ์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณธ โ€œ์‚ฌ์„ค ๋ธŒ๋ผ์šฐ์ € ์บ์‹œโ€์™€ โ€œCDN ์บ์‹œโ€ ์ด ๋‘˜์„ ์ค‘์‹ฌ์œผ๋กœ ์ด์•ผ๊ธฐ ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

์บ์‹ฑ ์ œ์–ด

Cache-control HTTP/1.1 ๊ธฐ๋ณธ ํ—ค๋” ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํด๋ผ์ด์–ธํŠธ์— ์–ด๋–ป๊ฒŒ ์บ์‹ฑํ•  ์ง€๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Cache-Control: no-store
    ์บ์‹œ๋Š” ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ, ์„œ๋ฒ„ ์‘๋‹ต์— ๊ด€ํ•ด ์–ด๋–ค ๊ฒƒ๋„ ์ €์žฅํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค. ์š”์ฒญ์€ ์„œ๋ฒ„ ์ธก์œผ๋กœ ์ „์†ก๋˜๊ณ  ์ „์ฒด ์‘๋‹ต์€ ๋งค๋ฒˆ ๋‹ค์šด๋กœ๋“œ๋œ๋‹ค.

  • Cache-Control: no-cache
    ์บ์‹œ๋œ ๋ณต์‚ฌ๋ณธ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฆด๋ฆฌ์ฆˆ ํ•˜๊ธฐ ์ „์—, ์œ ํšจ์„ฑ ํ™•์ธ์„ ์œ„ํ•ด ์› ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

  • Cache-Control: private
    ์‘๋‹ต์ด ๋‹จ์ผ ์‚ฌ์šฉ์ž๋งŒ์„ ์œ„ํ•œ ๊ฒƒ์ด๋ฉฐ ๊ณต์œ  ์บ์‹œ์— ์˜ํ•ด ์ €์žฅ๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ์‚ฌ์„ค ๋ธŒ๋ผ์šฐ์ € ์บ์‹œ๋Š” ์ด๋Ÿฐ ๊ฒฝ์šฐ์— ์‘๋‹ต์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, public ์บ์‹œ์ธ CDN ๋“ฑ์—์„œ ์‘๋‹ต์„ ์บ์‹œํ•  ์ˆ˜ ์—†๋‹ค.

  • Cache-Control: public
    ์‘๋‹ต์ด ์–ด๋–ค ์บ์‹œ์— ์˜ํ•ด์„œ๋“  ์บ์‹œ๋˜์–ด๋„ ์ข‹๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

  • Cache-Control: max-age=31536000
    ๋ฆฌ์†Œ์Šค๊ฐ€ ์œ ํšจํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋Š” ์ตœ๋Œ€ ์‹œ๊ฐ„์„ ๋งํ•œ๋‹ค. Expires๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์–ด๋„ ๊ทธ๋ณด๋‹ค ์šฐ์„ ํ•˜๋ฉฐ, ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์„ ํŒŒ์ผ์— ๋Œ€ํ•ด ๊ธด ์‹œ๊ฐ„์„ ์บ์‹ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Cache-Control: must-revalidate
    ์บ์‹œ๋Š” ์˜ค๋ž˜๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๊ทธ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ  ๋งŒ๋ฃŒ๋œ ๋ฆฌ์†Œ์Šค๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผํ•œ๋‹ค.

์บ์‹œ ์œ ํšจ์„ฑ

  • Cache-control: max-age=N
  • Expires
  • ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํœด๋ฆฌ์Šคํ‹ฑ
    • Last-Modified

์บ์‹œ ๊ฒ€์ฆ

  • Cache-control: must-revalidate
  • Advanced->Cache ํ™˜๊ฒฝ์„ค์ • ํŒจ๋„ ๋‚ด์— ์บ์‹œ ๊ฒ€์ฆ ํ™˜๊ฒฝ ์„ค์ •
  • ๊ฐ•ํ•œ ๊ฒ€์ฆ
    • ETags
  • ์•ฝํ•œ ๊ฒ€์ฆ
    • Last-Modified

์บ์‹œ ๋ฌดํšจํ™”

  • CDN ์บ์‹œ ๋ฌดํšจํ™”๋Š” ํ•ด๋‹น ํ”Œ๋žซํผ์—์„œ ์ œ๊ณต
  • ๋ธŒ๋ผ์šฐ์ € ์บ์‹œ ๋ฌดํšจํ™”๋Š” ๋ถˆ๊ฐ€๋Šฅ
    • ์บ์‹œ ๋ฒ„์ŠคํŒ…(Cache Busting)
      • content / chunk hash
      • version

๐Ÿง ์ •๋ฆฌ์™€ ๊ฐœ์„ ๊ฒฐ๊ณผ ๋ณด๊ธฐ

์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ๋ถ„์„๊ณผ์ •์—์„œ ๋‚˜์˜จ ๋ฌธ์ œ์ ๋“ค์„ ํ•ด๊ฒฐํ•ด๋ณด์•˜๋‹ค! ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด ๋ฐฉ๋ฒ•๋“ค ์ด์™ธ์—๋„ ๋” ์žˆ์œผ๋‚˜, ๋‹ค์Œ ๊ธ€์ธ ๋ Œ๋”๋งํŽธ์—์„œ ๋‹ค๋ฃจ๊ฑฐ๋‚˜, ํ˜น์€ ๋‹ค๋ฃจ์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•๋“ค์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค! ๊ทธ๋Ÿฐ ๋ฐฉ๋ฒ•๋“ค์€ ์ฐธ๊ณ ์šฉ์œผ๋กœ ์•„๋ž˜์— ํ‚ค์›Œ๋“œ๋งŒ ๊ฐ€๋ณ๊ฒŒ ์ ์–ด๋‘๋„๋ก ํ•˜๊ฒ ๋‹ค.

์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ค„์ด๊ธฐ: srcset, web font,
ํ•„์š”ํ•  ๋•Œ ํ•„์š”ํ•œ ๊ฒƒ ์š”์ฒญํ•˜๊ธฐ: HTTP/1.1 vs HTTP/2, preload, prefetch, preconnect, defer, async

๋ ˆ๋ฒจ๋กœ๊ทธ์—์„œ๋Š” ์œ„์˜ ๋ฐฉ๋ฒ•์˜ ์ผ๋ถ€์™€ ๋” ํ•„์š”ํ•œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ํ™œ์šฉํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฐœ์„ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ๋‹ค.
์„ฑ๋Šฅ ๋ถ„์„์€ "FAST 3G" ํ™˜๊ฒฝ์—์„œ ์ง„ํ–‰ํ–ˆ๋‹ค.

๋„คํŠธ์›Œํฌ ํŽ˜์ด๋กœ๋“œ


Lighthouse


WebPageTest


๐Ÿ“– ์ฐธ๊ณ ์ž๋ฃŒ

profile
์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค 4๊ธฐ ์›น ํ”„๋ก ํŠธ์—”๋“œ

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2022๋…„ 9์›” 12์ผ

gzip ๊ด€๋ จํ•œ ์ •๋ณด๊นŒ์ง€ ๐Ÿ‘๐Ÿ‘

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ