๋ฐ˜์‘ํ˜•

Intro


ํ”„๋ก ํŠธ์—”๋“œ ์˜์—ญ์—์„  .jsx, .tsx, .vue ๋“ฑ์˜ ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง„ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ํŒŒ์ผ๋“ค์€ ๋ชจ๋‘ .js ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. ๋ชจ๋“  ํŒŒ์ผ์„ ํ•˜๋‚˜์˜ .js ํŒŒ์ผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ๋ฐฉ์‹์€ ์„ฑ๋Šฅ์— ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋Œ€์‹  ์—ฌ๋Ÿฌ .js ํŒŒ์ผ(chunks)๋กœ ๋ณ€ํ™˜ํ•œ ๋’ค ํ•„์š”ํ•œ ์ˆœ๊ฐ„์—๋งŒ ๋กœ๋“œ(์ง€์—ฐ ๋กœ๋”ฉ)ํ•˜๋Š”๊ฒŒ ์„ฑ๋Šฅ์— ๋” ์œ ๋ฆฌํ•˜๋‹ค. ํŠนํžˆ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ์ค„์ผ ๋•Œ ์œ ์šฉํ•˜๋‹ค.

 

Vite, Webpack ๊ฐ™์€ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๋ณดํ†ต index, vendor ๋‘ ๊ฐœ์˜ ๋ฉ”์ธ chunk๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ฐธ๊ณ ๋กœ Vite 2.9 ๋ฒ„์ „๋ถ€ํ„ด Production ์ข…์†์„ฑ ๋ชจ๋“ˆ์ด index chunk์— ํฌํ•จ๋œ๋‹ค.

  • index : App.tsx์™€ ๊ฐ™์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ์ฝ”๋“œ
  • vendor : package.json - dependencies ์„น์…˜์— ๋ช…์‹œ๋œ ์ข…์†์„ฑ

 

Vite ๊ธฐ๋ณธ ์„ค์ •์œผ๋กœ ๋นŒ๋“œํ•ด๋ณด๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ index ์ฒญํฌ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. chunk๋ฅผ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์–ด๋–ค ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ•˜๋“  'ํ•ฉ์ณ์ง„' index ์ฒญํฌ ๋ฉ์–ด๋ฆฌ๋ฅผ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

# ๋นŒ๋“œ ๊ฒฐ๊ณผ
dist/registerSW.js                                 0.13 kB
dist/manifest.webmanifest                          0.15 kB
dist/index.html                                    1.96 kB โ”‚ gzip:   1.02 kB
dist/assets/index-df6d6f21.css                    12.84 kB โ”‚ gzip:   1.03 kB
dist/assets/QueryErrorResetBoundary-30b62529.js    0.18 kB โ”‚ gzip:   0.16 kB
dist/assets/chunk-G5IOFHY7-58761137.js             1.58 kB โ”‚ gzip:   0.88 kB
dist/assets/app-68a6bb5a.js                        2.56 kB โ”‚ gzip:   1.20 kB
dist/assets/index-6b503c34.js                      7.12 kB โ”‚ gzip:   2.70 kB
dist/assets/index-91b8ad77.js                    577.07 kB โ”‚ gzip: 157.92 kB
dist/assets/index-a08b75ea.js                    787.30 kB โ”‚ gzip: 253.44 kB

 

๐Ÿ” Rollup Plugin Visualizer ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ์™€ ๊ตฌ์กฐ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ๋ชจ๋“ˆ์˜ ํฌ๊ธฐ, ์˜์กด์„ฑ, ๋ฒˆ๋“ค์—์„œ ์ฐจ์ง€ํ•˜๋Š” ์‚ฌ์ด์ฆˆ ๋น„์œจ ๋“ฑ์„ ํŠธ๋ฆฌ๋งต ํ˜น์€ ๋ผ์ธ ์ฐจํŠธ ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•œ๋‹ค.

 

 

๐Ÿ” Vite๋Š” Vue.js ์ฐฝ์‹œ์ž Evan You(ๅฐค้›จๆบช)๊ฐ€ ๋งŒ๋“  ์›น ๋นŒ๋“œ ๋„๊ตฌ๋กœ, ์•„๋ž˜ ๋‘ ๊ฐ€์ง€ ํŠน์ง•์„ ๊ฐ–๋Š”๋‹ค.

  • Native ES Modules ๊ธฐ๋ฐ˜์˜ ๊ฐœ๋ฐœ ์„œ๋ฒ„: ES Modules๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ง์ ‘ ์ง€์›ํ•˜๋ฏ€๋กœ ๋ฒˆ๋“ค๋ง ๊ณผ์ • ์—†์ด ๋ชจ๋“ˆ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๋น ๋ฅธ ๋ฆฌ๋กœ๋“œ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•œ๋‹ค.  
  • ํŒŒ์ผ ํ†ตํ•ฉ์—” esbuild, ๋ฒˆ๋“ค๋ง์—” Rollup ์‚ฌ์šฉ: esbuild๋Š” Go๋กœ ์ž‘์„ฑ๋œ ๊ณ ์„ฑ๋Šฅ ๋ฒˆ๋“ค๋Ÿฌ/ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋‹ค. ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์—์„  ํŠธ๋ฆฌ ์‰์ดํ‚น ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” Rollup์„ ์‚ฌ์šฉํ•˜์—ฌ ํšจ์œจ์ ์ธ ๊ฒฐ๊ณผ๋ฌผ์„ ์ƒ์„ฑํ•œ๋‹ค. 

 

Vendor ์ฒญํฌ ๋ถ„๋ฆฌ


Vite 2.9 ๋ฒ„์ „๋ถ€ํ„ด ๊ธฐ๋ณธ์ ์œผ๋กœ vendor ์ฒญํฌ๋ฅผ ๋ถ„๋ฆฌํ•˜์ง€ ์•Š์ง€๋งŒ splitVendorChunkPlugin ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒค๋” ๋ชจ๋“ˆ๋งŒ ๋ณ„๋„์˜ ์ฒญํฌ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

// vite.config.ts
import { splitVendorChunkPlugin } from 'vite';

export default defineConfig({
  plugins: [react(), splitVendorChunkPlugin()],
});

 

ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์ •ํ•˜๊ณ  ๋นŒ๋“œํ•ด๋ณด๋ฉด vendor-*.js ์ด๋ฆ„์˜ ์ฒญํฌ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. index ์ฒญํฌ๋Š” ๋ฒค๋” ๋ชจ๋“ˆ์ด ์ œ๊ฑฐ๋ผ์„œ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ค„์—ˆ์ง€๋งŒ, vendor ์ฒญํฌ๋Š” 832 kB ์ •๋„๋กœ ๊ฝค ๋น„๋Œ€ํ•ด์กŒ๋‹ค.

# ๋นŒ๋“œ ๊ฒฐ๊ณผ
dist/registerSW.js                0.13 kB
dist/manifest.webmanifest         0.15 kB
dist/index.html                   2.04 kB โ”‚ gzip:   1.05 kB
dist/assets/index-df6d6f21.css   12.84 kB โ”‚ gzip:   1.03 kB
dist/assets/app-04f6ef89.js       2.21 kB โ”‚ gzip:   1.03 kB
dist/assets/index-8be5580d.js     6.86 kB โ”‚ gzip:   2.56 kB
dist/assets/index-995e1624.js    21.26 kB โ”‚ gzip:   6.72 kB
dist/assets/index-9413cf69.js   501.03 kB โ”‚ gzip: 135.67 kB
dist/assets/vendor-16e06f2d.js  832.65 kB โ”‚ gzip: 267.41 kB

 

Manual Chunks


Rollup์—์„œ ์ œ๊ณตํ•˜๋Š” manualChunks ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด vendor ์ฒญํฌ๋ฅผ ๋” ์ž‘์€ ๋‹จ์œ„๋กœ ์ชผ๊ฐค ์ˆ˜ ์žˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ข…์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ด ์ข…์†์„ฑ๋“ค์ด ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ๋กœ ๋กœ๋“œ๋ผ์•ผ ํ•œ๋‹ค. ์ฒญํฌ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ƒ์„ฑํ•  ๋•Œ ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ถ€๋ถ„ ์ค‘ ํ•˜๋‚˜๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด react-router-dom ํŒจํ‚ค์ง€๋Š” @remix-run/router, react-router์— ์˜์กด์ ์ด๋ฏ€๋กœ ์ด๋“ค์„ ๋™์ผํ•œ ์ฒญํฌ์— ํฌํ•จ์‹œ์ผœ์•ผ ํ•œ๋‹ค.

# react-router-dom ํŒจํ‚ค์ง€์˜ ์˜์กด์„ฑ ํ™•์ธ ๋ช…๋ น์–ด

# { '@remix-run/router': '1.9.0', 'react-router': '6.16.0' }
npm show react-router-dom dependencies

# { react: '^18.2.0', 'react-dom': '^18.2.0' }
npm show react-router-dom devDependencies

 

๐Ÿ” splitVenderChunkPlugin ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ๋•Œ manualChunks๋Š” ํ•จ์ˆ˜ ํ˜•ํƒœ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

manualChunks๋Š” ํ•จ์ˆ˜์™€ ๊ฐ์ฒด ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ ์†์„ฑ์€ ์ฒญํฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ , ์ฒญํฌ ์ด๋ฆ„์€ ์†์„ฑ ํ‚ค๋กœ ๊ฒฐ์ •๋œ๋‹ค. ํ•จ์ˆ˜ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๋ชจ๋“ˆ ID๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š”๋‹ค. ํ•จ์ˆ˜๊ฐ€ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ํ•ด๋‹น ID์˜ ๋ชจ๋“ˆ๊ณผ ๋ชจ๋“  ์˜์กด์„ฑ์ด ๋ฌธ์ž์—ด ์ด๋ฆ„์˜ ์ฒญํฌ์— ์ถ”๊ฐ€๋œ๋‹ค.

// ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•  ๋•Œ
manualChunks: {
  lodash: ['lodash'], // 'lodash' ๋ชจ๋“ˆ์„ 'lodash' ์ฒญํฌ๋กœ ๊ทธ๋ฃนํ•‘
}
// ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ๋•Œ
manualChunks(id) {
  // 'node_modules'๋ฅผ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์€ 'vendor' ์ฒญํฌ๋กœ ๊ทธ๋ฃนํ•‘
  if (id.includes('node_modules')) return 'vendor';
}

 

์•„๋ž˜๋Š” react-router-dom ๋ชจ๋“ˆ๊ณผ ๊ด€๋ จ๋œ ์˜์กด์„ฑ์„ @react-router๋ผ๋Š” ์ด๋ฆ„์˜ ์ฒญํฌ๋กœ ๊ทธ๋ฃนํ•‘ํ•œ ์˜ˆ์‹œ.

// vite.config.ts
import { splitVendorChunkPlugin } from 'vite';

export default defineConfig({
  plugins: [react(), splitVendorChunkPlugin()],
  build: {
    rollupOptions: {
      output: {
        manualChunks(id: string) {
          const reactRouterDeps = [
            '@remix-run',
            'react-router',
            'react-router-dom',
          ];
          if (reactRouterDeps.some((lib) => id.includes(lib)))
            return '@react-router';
        },
      },
    },
  },
});

 

์œ„ Vite ์„ค์ •์œผ๋กœ ๋นŒ๋“œํ•ด๋ณด๋ฉด @react-router ์ด๋ฆ„์˜ ์ฒญํฌ ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. vendor ์ฒญํฌ ์šฉ๋Ÿ‰์€ @react-router ์ฒญํฌ ํฌ๊ธฐ(50 kB)๋งŒํผ ๊ฐ์†Œํ–ˆ๋‹ค.

# ๋นŒ๋“œ ๊ฒฐ๊ณผ
dist/registerSW.js                       0.13 kB
dist/manifest.webmanifest                0.15 kB
dist/index.html                          2.12 kB โ”‚ gzip:   1.07 kB
dist/assets/index-df6d6f21.css          12.84 kB โ”‚ gzip:   1.03 kB
dist/assets/app-c7e6b312.js              2.29 kB โ”‚ gzip:   1.06 kB
dist/assets/index-049072fc.js            6.91 kB โ”‚ gzip:   2.58 kB
dist/assets/index-bfb7ca8b.js           21.44 kB โ”‚ gzip:   6.75 kB
dist/assets/@react-router-eb1c5b4a.js   50.25 kB โ”‚ gzip:  17.34 kB
dist/assets/index-e3190f43.js          501.06 kB โ”‚ gzip: 135.69 kB
dist/assets/vendor-0663586e.js         781.40 kB โ”‚ gzip: 250.49 kB

 

์˜์กด์„ฑ ๊ธฐ์ค€์œผ๋กœ ๋ถ„๋ฆฌ โญ


๐Ÿ” package.json.dependencies๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋ ค๋ฉด tsconfig.node.json.include ๋ฐฐ์—ด์— package.json ๊ฒฝ๋กœ๋ฅผ ํฌํ•จ์‹œ์ผœ์•ผ ํ•œ๋‹ค. e.g. "include": ["vite.config.ts", "package.json"]

 

ํŒจํ‚ค์ง€ ์˜์กด์„ฑ๊ณผ ๋กœ๋“œ ์ˆœ์„œ๋ฅผ ์ผ์ผ์ด ํŒŒ์•…ํ•ด์„œ ์ฒญํฌ๋ฅผ ์ˆ˜๋™ ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์€ ๋ฒˆ๊ฑฐ๋กญ๋‹ค. ๋Œ€์‹  โ‘ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”์ธ ํ”„๋ ˆ์ž„์›Œํฌ(React)์™€ ๊ด€๋ จ ํŒจํ‚ค์ง€๋ฅผ vendor ์ฒญํฌ๋กœ ๋ฌถ๊ณ , โ‘ก๋‚˜๋จธ์ง€๋Š” package.json์˜ ์ข…์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ฒญํฌ๊ฐ€ ์ž๋™ ๋ถ„๋ฆฌ๋˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

// vite.config.ts
import { dependencies } from './package.json';
// dependencies: { axios: '^1.5.0', jotai: '^2.4.2', ... }

// React ๊ด€๋ จ ์˜์กด์„ฑ ํ•„ํ„ฐ๋ง
const reactDeps = Object.keys(dependencies).filter(
  (key) => key === 'react' || key.startsWith('react-'),
);

const manualChunks = {
  // 'vendor' chunk์— ๋ชจ๋“  React ๊ด€๋ จ ์˜์กด์„ฑ ํฌํ•จ
  vendor: reactDeps,
  // ๋‚˜๋จธ์ง€ ์˜์กด์„ฑ์— ๋Œ€ํ•ด ์ถ”๊ฐ€์ ์ธ chunk ์ƒ์„ฑ
  ...Object.keys(dependencies).reduce((chunks, name) => {
    // 'vendor'์— ์ด๋ฏธ ํฌํ•จ๋œ ์˜์กด์„ฑ์€ ๊ฑด๋„ˆ๋›ฐ๊ธฐ
    if (!reactDeps.includes(name)) chunks[name] = [name];
    return chunks;
  }, {}),
};

export default defineConfig({
  plugins: [react()],
  build: { rollupOptions: { output: { manualChunks } } },
});
๋”๋ณด๊ธฐ
{
  vendor: [
    'react',
    'react-dom',
    'react-error-boundary',
    'react-hook-form',
    'react-router-dom',
    'react-tsparticles'
  ],
  '@chakra-ui/react': [ '@chakra-ui/react' ],
  '@fingerprintjs/fingerprintjs': [ '@fingerprintjs/fingerprintjs' ],
  '@formkit/auto-animate': [ '@formkit/auto-animate' ],
  '@hookform/resolvers': [ '@hookform/resolvers' ],
  '@tanstack/react-query': [ '@tanstack/react-query' ],
  '@vercel/analytics': [ '@vercel/analytics' ],
  axios: [ 'axios' ],
  'date-fns': [ 'date-fns' ],
  'framer-motion': [ 'framer-motion' ],
  jotai: [ 'jotai' ],
  nanoid: [ 'nanoid' ],
  qs: [ 'qs' ],
  sass: [ 'sass' ],
  yup: [ 'yup' ]
}

 

์œ„ ์„ค์ •์„ ์ ์šฉํ•˜๊ณ  ๋นŒ๋“œํ•ด ๋ณด๋ฉด ๊ธฐ์กด 781kB์˜€๋˜ vendor ์ฒญํฌ๊ฐ€ ์•ฝ 290kB ํฌ๊ธฐ์˜ ๋ฆฌ์•กํŠธ ๊ด€๋ จ ํŒจํ‚ค์ง€๋กœ ๊ทธ๋ฃนํ•‘๋˜๊ณ , vendor ์ฒญํฌ์— ์žˆ๋˜ ์˜์กด์„ฑ๋“ค์€ ๊ฐ๊ฐ ๊ฐœ๋ณ„ ์ฒญํฌ๋กœ ๋ถ„๋ฆฌ๋๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•˜๊ณ , ์‚ฌ์šฉ์ž๋Š” ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋งŒ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

# ๋นŒ๋“œ ๊ฒฐ๊ณผ
dist/registerSW.js                                      0.13 kB
dist/manifest.webmanifest                               0.15 kB
dist/index.html                                         2.60 kB โ”‚ gzip:   1.17 kB
dist/assets/index-df6d6f21.css                         12.84 kB โ”‚ gzip:   1.03 kB
dist/assets/@fingerprintjs/fingerprintjs-4ed993c7.js    0.00 kB โ”‚ gzip:   0.02 kB
dist/assets/@vercel/analytics-4ed993c7.js               0.00 kB โ”‚ gzip:   0.02 kB
dist/assets/sass-4ed993c7.js                            0.00 kB โ”‚ gzip:   0.02 kB
dist/assets/nanoid-20264c15.js                          0.44 kB โ”‚ gzip:   0.31 kB
dist/assets/@hookform/resolvers-6186e247.js             0.76 kB โ”‚ gzip:   0.43 kB
dist/assets/app-ee4ec089.js                             1.25 kB โ”‚ gzip:   0.59 kB
dist/assets/jotai-5371d6c6.js                           5.52 kB โ”‚ gzip:   2.42 kB
dist/assets/@formkit/auto-animate-99b7ba86.js           5.77 kB โ”‚ gzip:   2.45 kB
dist/assets/index-10a9dd48.js                           7.10 kB โ”‚ gzip:   2.68 kB
dist/assets/date-fns-1253a22e.js                       26.79 kB โ”‚ gzip:   7.52 kB
dist/assets/axios-599d2e10.js                          29.03 kB โ”‚ gzip:  11.62 kB
dist/assets/qs-c2440112.js                             31.85 kB โ”‚ gzip:  10.57 kB
dist/assets/yup-4151e337.js                            35.43 kB โ”‚ gzip:  11.58 kB
dist/assets/@tanstack/react-query-512219a8.js          39.93 kB โ”‚ gzip:  11.01 kB
dist/assets/index-653ca8f3.js                          56.92 kB โ”‚ gzip:  18.33 kB
dist/assets/framer-motion-5b367961.js                 101.02 kB โ”‚ gzip:  34.13 kB
dist/assets/vendor-ead95c8e.js                        290.76 kB โ”‚ gzip:  92.84 kB
dist/assets/@chakra-ui/react-03b491e2.js              300.44 kB โ”‚ gzip:  99.47 kB
dist/assets/index-7c561f25.js                         422.93 kB โ”‚ gzip: 109.15 kB

 

๋ ˆํผ๋Ÿฐ์Šค


 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”

 

๋ฐ˜์‘ํ˜•