๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ™ˆ > ๋ ˆ๋ฒจ์—…์˜ ํ…Œํฌ๋…ธํŠธ

[ํ”„๋ก ํŠธ์—”๋“œ] Vue build time ์ตœ์ ํ™” ํ•ด๋ณด๊ธฐ

by Blog.Bigpico eddie0329 2021. 7. 12.

๐Ÿ“Œ ๋ชฉ์ฐจ

  • ์„œ๋ก 
  • usedExport ๋‚˜๋ผ ํƒ๋ฐฉ
  • devtool ๋ฌด๊ธฐ ํš๋“
  • webpack-bundle-analyzer ์„ธ๊ณ„ ์ง€๋„ ํš๋“
  • Element-UI ๋‚˜๋ผ์™€์˜ ์ „์Ÿ ๊ทธ๋ฆฌ๊ณ  ํŒจ๋ฐฐ…
  • Lottie.js ๋‚˜๋ผ์™€์˜ ์ „์Ÿ
  • ๊ฒฐ๋ก 

๐Ÿ“Œ ์„œ๋ก 

์•ˆ๋…•ํ•˜์„ธ์š”. ๋น…ํ”ฝ์ฒ˜์—์„œ ์ข…์„ ๋ฒ„๋ฅผ ๋งก๊ณ  ์žˆ๋Š” ์ตœ์ข…์„ ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ™‡

์š”์ฆ˜ ๊ฑธ๋ฆฌ๋ฒ„ ์—ฌํ–‰๊ธฐ๋ฅผ ๋„ˆ๋ฌด ์žฌ๋ฐŒ๊ฒŒ ์ฝ๊ณ  ์žˆ์–ด์„œ main ํ”„๋กœ์ ํŠธ์—์„œ build ์ตœ์ ํ™”๋ฅผ ์‹œํ‚ค๋Š”๋ฐ ๊ธฐ์Šน์ „๊ฒฐ์˜ ํ˜•์‹์œผ๋กœ ์žฌ๋ฐŒ๊ฒŒ ํ’€์–ด๋‚˜๊ฐ€๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์žฌ๋ฐŒ๊ฒŒ ์ฝ์–ด์ฃผ์„ธ์š”! (ํ”ผ๋“œ๋ฐฑ๋„ ๋„ˆ๋ฌด๋‚˜ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ) ๊ทธ๋Ÿผ ์ถœ๋ฐœ ! ๐Ÿš€

๐Ÿ“Œ usedExport ๋‚˜๋ผ ํƒ๋ฐฉ

๐Ÿ’ก ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋“ค์ด build๊ฐ€ ๋˜๋Š” ๋ชจ์Šต์„ ๋ณด์•˜๊ณ  ๋‚˜๋Š” ๊ทธ๊ฑธ ์—†์• ๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์˜ค๋žœ๋งŒ์— ์ฒซ ์ถœ๊ทผ์„ ํ•˜์—ฌ ๋“ค๋œฌ ๋งˆ์Œ์œผ๋กœ build๊ฐ€ ๋œ main.js๋ฅผ ์ฝ๊ณ  ์žˆ์—ˆ์„๋•Œ ์˜€์Šต๋‹ˆ๋‹ค… ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋“ค์ด ์šฐํ›„์ฃฝ์ˆœ์œผ๋กœ ๋ถ™์–ด์žˆ๋Š”๊ฑธ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
๋งˆ์นจ webpack tree shaking์ด ๋– ์˜ค๋ฅด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ณ ์ž webpack์—์„œ optimization(usedExports)์„ ์„ค์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿšจ usedExports ๋ž€?
ํ•ด๋‹น ๊ฐ’์€ bool์˜ ๊ฐ’์œผ๋กœ ์„ ํƒ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ exports์ด์ง€๋งŒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋Š” ๋นŒ๋“œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. production๋ชจ๋“œ ์ผ๋•Œ๋Š” default๋กœ true๊ฐ€ ์ • ์ด ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

 

// vue.config.js

configureWebpack: config => {
    if (!config.optimization) config.optimization = {};
    config.optimization.usedExports = true;
  },
์ ์šฉ ์ „ ์ ์šฉ ํ›„

main.js์˜ ํฌ๊ธฐ๋ฅผ 19.9MB -> 19.6MB๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

0.3MB๋ฅผ ์ค„์ธ ์…ˆ์ด๋‹ˆ 1๋ฐ”์ดํŠธ๊ฐ€ ๊ธ€์ž ํ•˜๋‚˜๋‹ˆ ๋ณดํ†ต ํ‰๊ท  ํ•œ์ค„์ด 60๋ฐ”์ดํŠธ๋ผ๊ณ  ๊ฐ€์ •์„ ํ•œ๋‹ค๋ฉด ์•ฝ 5000์ค„์„ ์ค„์ธ์…ˆ ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ข…์„ ๋ฒ„๋Š” ์ด๊ฒƒ์œผ๋กœ ๋งŒ์กฑ์„ ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ข€ ๋” ๊ฐ•๋ ฅํ•œ ์ „์„ค์˜ ๋ฌด๊ธฐ๋ฅผ ์ฐพ์•„ ๋– ๋‚˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ devtool ๋ฌด๊ธฐ ํš๋“

๐Ÿ’ก source-map์€ ์ž˜ ์••์ถ•ํ•ด์ค€๋‹ค๋Š” ์žฅ์ ์€ ์žˆ์ง€๋งŒ ๋Š๋ฆฌ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

์•„์ง build์˜ ์†๋„๋ฅผ ๊ฐ์•ˆํ•ด๋ดค์„๋•Œ ๊ทผ๋ณธ์ ์ธ ๋ถ€๋ถ„์„ ํ•ด๊ฒฐ์„ ๋ชปํ•œ๊ฒƒ ๊ฐ™์€ ๋Š๋‚Œ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ devtools๊ด€๋ จ ๋งํฌ๋ฅผ ์ฐพ์•„๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

๊ทธ๋ž˜์„œ devtool source-map์—์„œ eval๋กœ ๋ฌด๊ธฐ๋ฅผ ๋Œ€์ฒด ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ production mode ์ด๊ฑฐ๋‚˜ development mode ๋‘๊ฐœ๋‹ค devtool๋กœ source-map์„ ์‚ฌ์šฉํ•ด์ฃผ๊ณ  ์žˆ๋Š”๋ฐ ์ด์ œ development mode ์ผ๋•Œ ๊ฐ€์žฅ ๋น ๋ฅด๋‹ค๋Š” eval์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ๋ฌด๊ธฐ๋กœ ๋Œ€์ฒด ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

// vue.config.js

configureWebpack: config => {
    config.devtool = isDevOrLocal ? 'eval' : 'source-map';
  },

์ด ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฝค ๋งŽ์€ ์‹œ๊ฐ„์„ ์ค„์ผ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ ์ข…์„ ๋ฒ„๋Š” ์กฐ๊ธˆ ๋” ๊ณผ๊ฐํ•œ ์„ ํƒ์„ ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ webpack-bundle-analyer ์„ธ๊ณ„ ์ง€๋„ ํš๋“

๐Ÿ’ก ์„ธ๊ณ„์—๋Š” ํฐ ์™•๊ตญ์ด ์ด๋ฏธ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์—ˆ๋‹ค.

 

์กฐ๊ธˆ ๋” ๊ณผ๊ฐํ•œ ์„ ํƒ์„ ํ•˜๊ธฐ์— ์•ž์„œ ์‹ค์ œ bundle์˜ ํฌ๊ธฐ๋ฅผ ์•Œ ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ•ด๋‹น ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์•Œ๋ ค์ฃผ๋Š” webpack-bundle-analyzer๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์น˜๋ฅผ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

// vue.config.js

// ๐Ÿšง Intentinally commented - by eddie
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

configureWebpack: config => {

    // ๐Ÿšง Intentinally commented only used for anaylzing bundle - by eddie
    config.plugins.push(new BundleAnalyzerPlugin());
  },

 

๊ทธ๋ ‡๊ฒŒ ์ž‘์—…์ด ๋๋‚œํ›„ ์–ด๋–ค ๋ฒˆ๋“ค์˜ ํฌ๊ธฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋˜์–ด์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿ“Œ Element-UI ๋‚˜๋ผ์™€์˜ ์ „์Ÿ ๊ทธ๋ฆฌ๊ณ  ํŒจ๋ฐฐ...

๐Ÿ’ก ๋„ˆ๋ฌด๋‚˜ ๊ฐ•๋ ฅํ•œ ์ƒ๋Œ€๋ฅผ ๋งŒ๋‚˜ ์ขŒ์ ˆ

 

์„ธ๊ณ„ ์ง€๋„๋ฅผ ํš๋“ํ›„ ํŒจ๊ธฐ๋กญ๊ฒŒ ๊ฐ€์žฅ ๋งŽ์€ ์˜์—ญ์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋Š” Element-ui ๋‚˜๋ผ๋ฅผ ์ •๋ณตํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ฐฉ๋ฒ•์œผ๋กœ cdn์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด ํ•ด๋‹น ๋ฐฉ๋ฒ•๋ก ์œผ๋กœ ๊ณต๋žต์„ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋‚ด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿšง ๋ฌธ์ œ์ ๋“ค?

  • Element ui ์ž์ฒด๊ฐ€ ์ „์—ญ์— ์„ ์–ธ์ด ๋˜์–ด์žˆ์ง€ ์•Š๊ณ  ๊ฐ๊ฐ์˜ ํŒŒ์ผ๋“ค๋กœ ์„ ์–ธ๋˜์–ด Vue.use()์˜ ์˜์กด์„ฑ์„ ์ œ๊ฑฐํ•˜๊ธฐ๊ฐ€ ํž˜๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. (์•ฝ 110๊ฐœ์˜ ํŒŒ์ผ๋“ค)
  • ์ œ๊ฑฐ ํ•˜๋”๋ผ๋„ element ui dark theme์œผ๋กœ css ์ž์ฒด๊ฐ€ ๊นจ์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ์ ๋“ค ๋•Œ๋ฌธ์— cdn์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ๋ฐฉ๋ฒ•์œผ๋กœ์˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์„ ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ํฐ ์ˆœ์„œ๊ฐ€ ์•„๋‹Œ ์˜์กด์„ฑ์ด ๋งŽ์ด ์—ฎ์—ฌ์žˆ์ง€ ์•Š์ง€๋งŒ ํŒŒ์ผ์ด ํฐ ๊ฒƒ์„ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ Lottie.js ๋‚˜๋ผ์™€์˜ ์ „์Ÿ

๐Ÿ’ก ํ•œ๋ฒˆ์˜ ํŒจ๋ฐฐ ์ดํ›„ ์ „๋žต์„ ์ˆ˜์ •ํ•˜์—ฌ ๋Œ€์Šน๋ฆฌ

 

์œ„์˜ ๊ตํ›ˆ์„ ํ† ๋Œ€๋กœ ์ •๋ฆฌํ•ด๋ณธ ๊ฒฐ๊ณผ `lottie.js ๋ผ๋Š” ํƒ€๊ฒŸ`์ด ๋ˆˆ์— ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค.

 

  • ์˜์กด์„ฑ์ด ์ ์–ด์•ผ ํ•จ → ์ด 4๊ฐœ์˜ ํŒŒ์ผ์—์„œ Lottie.js๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ.
  • ๋ฒˆ๋“ค์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์•ผํ•จ → ์œ„์˜ ๊ทธ๋ฆผ์—์„œ ๋ณด๋‹ค์‹ถ์ด ๋ฒˆ๋“คํฌ๊ธฐ๊ฐ€ 5๋ฒˆ์งธ๋กœ ํผ (element > lodash > sendbird > moment > lottie)

 

๊ทธ๋ ‡๊ฒŒ lottie.js๋ฅผ ๊ณต๋žต์„ ๊ฒฐ์ •ํ•˜๊ณ  index.html, index-dev.html์— ๊ฐ๊ฐ cdn์„ ์‚ฝ์ž…ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. async์™€ defer๋ฅผ ๊ฑธ์–ด์ฃผ์ง€ ์•Š์€ ์ด์œ ๋Š” ํ˜น์‹œ vue-script๊ฐ€ ์‹คํ–‰๋œ ์ดํ›„ ์‹คํ–‰์ด ๋˜์–ด๋ฒ„๋ฆด ์œ„ํ—˜์„ฑ์ด ์žˆ์–ด ์ƒ๋žต์„ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. (์ •๋ง ๋งŒ์•ฝ์˜ ๊ฒฝ์šฐ → 99.9%์˜ ๋Œ€๋ถ€๋ถ„ ๊ทธ๋ ‡์ง€ ์•Š์„๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐ์€ ํ–ˆ์Œ.)

 

 

<!-- index.html & index-dev.html -->

<!-- LOTTIE-WEB -->
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.6.10/lottie.min.js"
      integrity="sha512-QGaslwkb2XoQM7dTYUB8YucbFcUC+Mhm/xTkz+pXNv0Dm9aZSj1Js7OwXrXa1OrMJUpSi2Bj21srh8mwsFNKTQ=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    ></script>

 

๊ทธ๋ฆฌ๊ณ  vue.config.js์— externals๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

// vue.config.js

chainWebpack: config => {
    config.externals({
      IMP: 'IMP',
      'lottie-web': 'lottie',
    });
  },

๐Ÿšง webpack externals๋ž€?
import packages์˜ ๋ฒˆ๋“ค๋ง์„ ๋ง‰๊ณ  ์™ธ๋ถ€ dependecies๋ฅผ runtime์— ์ฃผ์ž… ์‹œํ‚ต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ lottie.js์™•๊ตญ์„ ๋ฉธ๋ง์‹œํ‚ฌ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰

 

 

๐Ÿ“Œ ๊ฒฐ๋ก 

๐Ÿ’ก ์˜คํ”ˆ์†Œ์Šค๋Š” ๋งค์ง์ด ๋„ˆ๋ฌด ๋งŽ์•„์š”. by ์ด๋ฌธ๊ตญ๋‹˜

 

์‹ค์ œ๋กœ ๋นŒ๋“œ๋ฅผ ์ตœ์ ํ™” ์‹œํ‚ค๋ฉด์„œ ์˜คํ”ˆ์†Œ์Šค๊ฐ€ ์ •๋ง ์–‘๋‚ ์˜ ๊ฒ€์ด๊ตฌ๋‚˜ ๋ผ๋Š” ์ƒ๊ฐ์„ ๋งŽ์ด ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

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

๊ธด๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ™‡

๋Œ“๊ธ€0