๋ฌธ์ œ

Nextjs ๋นŒ๋“œ๋ฅผ ํ•˜๋‹ค๊ฐ€ ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ์˜ ์—๋Ÿฌ๋กœ cd๊ฐ€ ์ œ๋Œ€๋กœ ๋Œ์•„๊ฐ€์ง€ ์•Š์•˜๋‹ค.

#11 167.9    Creating an optimized production build ...
#11 228.7 <w> [webpack.cache.PackFileCacheStrategy] Serializing big strings (253kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)
#11 305.0 
#11 305.0 <--- Last few GCs --->
#11 305.0 
#11 305.0 [26:0x773a1be6a000]   301008 ms: Mark-Compact (reduce) 457.7 (484.1) -> 447.8 (473.1) MB, pooled: 0 MB, 671.97 / 0.00 ms  (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 690 ms) (average mu = 0.270, curren
#11 305.0 
#11 305.0 <--- JS stacktrace --->
#11 305.0 
#11 305.0 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
#11 305.0 ----- Native stack trace -----
#11 305.0 
#11 ERROR: process "/bin/sh -c yarn build" did not complete successfully: exit code: 129

๋ฌธ์ œ ๋ถ„์„ํ•˜๊ธฐ

๋กœ๊ทธ๋ฅผ ํ•œ๋ฒˆ์”ฉ ๋œฏ์–ด๋ณด์ž

  1. Serializing big strings (253kiB) impacts deserialization performance
    • Webpack ์บ์‹œ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ โ€œ253 KiB์งœ๋ฆฌ ํฐ ๋ฌธ์ž์—ดโ€์„ ์ง๋ ฌํ™”ํ–ˆ๋‹ค๋Š” ๊ฒฝ๊ณ ์ž…๋‹ˆ๋‹ค.
    • ์ด๋Ÿฐ ํฐ ๋ฌธ์ž์—ด์„ ๊ณ„์† ์ฒ˜๋ฆฌํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ํฌ๊ฒŒ ๋Š”๋‹ค
    • ์ด๊ฒƒ๋„ ์•ž์œผ๋กœ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๋ฌธ์ œ์ด์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค
  2. ๋งˆ์ง€๋ง‰ GC ๋กœ๊ทธ Mark-Compact (reduce) 457.7 MB โ†’ 447.8 MB โ€ฆ Ineffective mark-compacts near heap limit
    • V8(=Node.js ์—”์ง„)์ด โ€œMark-Compactโ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜๋ณตํ–ˆ์ง€๋งŒ, ํž™ ์ƒํ•œ ๊ทผ์ฒ˜๋ผ์„œ ์ถฉ๋ถ„ํžˆ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ ๋ชปํ–ˆ์Œ
  • FATAL ERROR: โ€ฆ JavaScript heap out of memory
    • Node.js ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋” ์ด์ƒ ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋Š˜๋ฆด ์ˆ˜ ์—†์–ด์„œ ๊ฐ•์ œ ์ข…๋ฃŒ
    • Node.js์˜ ๊ธฐ๋ณธ ํž™ ํ•œ๋„๋Š” ๋Œ€์ฒด๋กœ 500MB ์ •๋„๋ผ์„œ Webpack์ด ๊ทธ ์ด์ƒ์„ ์š”๊ตฌํ•˜๋ฉด ํ„ฐ์ง„๋‹ค
      • node -e 'console.log(v8.getHeapStatistics().heap_size_limit/(1024*1024))' ๋ช…๋ น์–ด๋กœ ํ˜„์žฌ ํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ œํ•œ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (MB๋‹จ์œ„)

์ด ๋ฌธ์ œ๋Š” ๋จผ์ € ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์“ฐ์ด๋Š” ์ง€๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค. ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ถ”์ ํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์ง€๋งŒ, ๋‹คํ–‰ํžˆ next 15๋ฒ„์ „๋ถ€ํ„ฐ๋Š” ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์“ฐ์˜€๋Š”์ง€ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋งจ๋“œ ์˜ต์…˜์„ ์ œ๊ณตํ•œ๋‹ค.

next build --experimental-debug-memory-usage
   ***************************************
   Memory usage report at "Finished build":
    - RSS: 1640.28 MB
    - Heap Used: 659.31 MB
    - Heap Total Allocated: 917.22 MB
    - Heap Max: 4144.00 MB
    - Percentage Heap Used: 15.91%
   ***************************************

 โœ“ Collecting page data    

   ***************************************
   Memory usage report at "Finished collecting page data":
    - RSS: 54.77 MB
    - Heap Used: 652.05 MB
    - Heap Total Allocated: 917.22 MB
    - Heap Max: 4144.00 MB
    - Percentage Heap Used: 15.73%
   ***************************************
   
Memory usage report:
    - Total time spent in GC: 792.17ms
    - Peak heap usage: 659.31 MB
    - Peak RSS usage: 1749.19 MB

์‹คํ–‰ ์‹œํ‚ค๋ฉด ์ด๋Ÿฐ ์‹์œผ๋กœ ์‚ฌ์šฉ๋Ÿ‰์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋กœ์ปฌ ๋‚ด ํ™˜๊ฒฝ์—์„œ๋Š” heap์„ ์ด๋ฏธ 4gb์ •๋„๋กœ ์„ค์ •ํ•ด๋‘” ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋œจ์ง€ ์•Š๊ณ  ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‚ด๊ฐ€ ๋„์›Œ๋†“์€ ec2 t2.micro์—์„œ๋Š” ์ด๋ฅผ ์„ค์ •ํ•ด๋‘์ง€ ์•Š์•„ ๋ฌธ์ œ๊ฐ€ ๋˜์—ˆ๋‹ค.

ํ˜น์‹œ๋‚˜ ์ƒํ˜ธ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š”์ง€๋„ ๋‹ค์‹œ ํ•˜๋‚˜์”ฉ ํ›‘์–ด๋ณด๋ฉด์„œ ์ฐพ์•„๋ดค๋Š”๋ฐ, ์ƒํ˜ธ์ฐธ์กฐ๋„ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์ ํ™”๋ณด๋‹ค๋Š” ๋น ๋ฅด๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ๋งŒ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์šฐ์„ ์ด๊ฒ ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€ ์ •๋„๊ฐ€ ์žˆ๋‹ค.

  1. Node.js ํž™๋ฉ”๋ชจ๋ฆฌ์˜ ์ œํ•œ์„ ๋Š˜๋ฆฌ๊ธฐ
  2. ๋นŒ๋“œ ๊ณผ์ •์—์„œ next.js์˜ experimental ๊ธฐ๋Šฅ ์‚ฌ์šฉํ•˜๊ธฐ

1. Node.js ํž™๋ฉ”๋ชจ๋ฆฌ์˜ ์ œํ•œ ๋Š˜๋ฆฌ๊ธฐ

"scripts": {
  "build": "NODE_OPTIONS='--max-old-space-size=4096' next build"
}

์ด๋Ÿฐ ์‹์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ์— ์˜ต์…˜์„ ๋‹ฌ์•„๋†“์œผ๋ฉด Nodejs์˜ ํž™๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์„ ๋Š˜๋ฆด ์ˆ˜ ์žˆ๋‹ค.

Next.js์˜ experimental ๊ธฐ๋Šฅ ์‚ฌ์šฉํ•˜๊ธฐ

Next.js ๋˜ํ•œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์ธ์ง€ํ•˜๊ณ  ์žˆ์—ˆ๊ณ , ์ ์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋Š˜์–ด๋‚  ์ˆ˜๋ก ํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์ด๋Ÿฐ ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•œ๋‹ค.

๋” ์ž์„ธํ•œ ์„ค๋ช…์€ ์—ฌ๊ธฐ ์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

WebpackMemoryOptimizations

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ next.config.ts์—์„œ experimental ์†์„ฑ ์ค‘ 15๋ฒ„์ „๋ถ€ํ„ฐ webpackMemoryOptimizations ์†์„ฑ์ด ์ถ”๊ฐ€๋๋‹ค๋Š” ๋ถ€๋ถ„์ด๋‹ค.

experimental ๊ธฐ๋Šฅ์ด๊ธด ํ•˜์ง€๋งŒ, ๋”ฐ๋กœ low-risk ํ•œ ๊ธฐ๋Šฅ์ด๋ผ๊ณ  ์ถ”๊ฐ€๋กœ ๋ง๋ถ™์—ฌ๋†“์€๊ฒƒ์„ ๋ณด๋ฉด ํฌ๊ฒŒ ๋ฌธ์ œ๋  ๋ถ€๋ถ„์€ ๋งŽ์ด ์—†๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

์˜ต์…˜์„ ํ™œ์„ฑํ™”ํ•˜๊ณ  ๋นŒ๋“œํ•ด๋ณด๋‹ˆ ์ •๋ง ํฌ๊ฒŒ ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ค„์–ด๋“ค์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋•๋ถ„์— ํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ œํ•œ์„ ๋ฐ”๊พธ์ง€ ์•Š๊ณ  ์†์„ฑ ํ•˜๋‚˜ ๋ฐ”๊ฟ”์„œ ๋ฌธ์ œ ํ•ด๊ฒฐ์ด ๊ฐ€๋Šฅํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์กฐ๊ธˆ ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์กฐ๊ธˆ์”ฉ ์“ฐ๊ธฐ ์œ„ํ•ด ๋” ์ž‘์€ ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•ด์„œ ๋นŒ๋“œ ์ž‘์—… ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š”๋ฐ, ๊ทธ๋งŒํผ ๋นŒ๋“œ ์‹œ๊ฐ„์€ ์ƒ์Šนํ•œ๋‹ค. trade-off๊ฐ€ ์‹ฌํ•œ ๊ฒƒ ๊ฐ™์•„ ์›ฌ๋งŒํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ง„ ๊ณณ์ด๋ผ๋ฉด ์ตœ์ ํ™”์™€ ํ•จ๊ป˜ node.js์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์„ ๋Š˜๋ฆฌ๋Š”๊ฒŒ ์ตœ์„ ์ด์ง€ ์•Š์„๊นŒ..

Webpack Build worker

์›นํŒฉ ๋นŒ๋“œ ์›Œ์ปค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณ„๋„์˜ Node.js ์›Œ์ปค ๋‚ด์—์„œ Webpack ์ปดํŒŒ์ผ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋นŒ๋“œ ์ค‘ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ค„์–ด๋“ค๊ฒŒ ๋œ๋‹ค.

์ •์  ๋ถ„์„ ์Šคํ‚ตํ•˜๊ธฐ

//next.config.ts
  eslint: {
    ignoreDuringBuilds: true,
  },
  typescript: {
    ignoreBuildErrors: true,
  },

๊ฒฐ๊ตญ ์ •์  ๋ถ„์„ ๋„๊ตฌ๋“ค๋„ ๋ฆฌ์†Œ์Šค๋ฅผ ์žก์•„๋จน๋Š” ์ผ์ด๊ณ , ๋ชจ๋“  ํŒŒ์ผ๋“ค์„ ๋ณด๋ฉด์„œ ๊ทœ์น™์— ์–ด๊ธ‹๋‚˜๋Š”์ง€ ํ•˜๋‚˜ํ•˜๋‚˜ ํŒŒ์‹ฑํ•˜๊ณ  ๋ถ„์„ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์ •์  ๋ถ„์„๋“ค์€ ๊ฐœ๋ฐœ ๋ฐ CI ๋‹จ์—์„œ ๋๋‚˜์•ผ ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ•˜์—ฌ ๋‚˜๋Š” CI์—์„œ ๋Œ๋ฆฐ ๋‹ค์Œ์— ๋นŒ๋“œ์—์„œ๋Š” ๋ณ„๋„์˜ runner์—์„œ ์‹คํ–‰ํ•˜๋„๋ก ํ•ด๋†จ๋‹ค.

serverSourceMaps

{
	experimental: {
		serverSourceMaps:false
	}
}

์ด๊ฒƒ๋„ experimental ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์†Œ์Šค ๋งต์€ ๋ฒˆ๋“ค๋œ JS โ†” ์›๋ณธ ์ฝ”๋“œ ๊ฐ„์˜ ๋งคํ•‘ ํŒŒ์ผ๋กœ, ๋ฒˆ๋“ค๋œ js๋Š” ์ด๋ฆ„์ด ๋ฐ”๋€Œ๋Š”๋ฐ ์ด์— ๋”ฐ๋ผ์„œ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋Š” ๋งŒํผ, ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์“ฐ์ธ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์†Œ์Šค ๋งต์˜ ๊ฒฝ์šฐ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ๊ฐ€ ์†Œ์Šค๋งต์ด ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค๋ฉด, ๋ณด์•ˆ์—๋„ ์ข‹์ง€ ์•Š๊ธฐ๋„ ํ•˜๊ณ  ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฆฌ์†Œ์Šค ์†Œ๋ชจํ•˜๋Š” ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์— false ์ฒ˜๋ฆฌํ•ด๋„ ๋นŒ๋“œ ์„ฑ๋Šฅ์€ ์กฐ๊ธˆ ์ข‹์•„์ง„๋‹ค.

๊ฒฐ๋ก 

  • ์›ฌ๋งŒํผ ๋ฆฌ์†Œ์Šค๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋„๊ฐ€ ์žˆ๋‹ค๋ฉด Nodejs์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์„ ๋Š˜๋ฆฌ์ž
  • ์‚ด์ง ๋น ๋“ฏํ•˜๋‹ค๋ฉด ์ฐจ๋ผ๋ฆฌ ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋Š˜๋ฆฌ๋Š” ๋Œ€์‹  WebpackMemoryOptimizations ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋นŒ๋“œ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•๋“ค์„ ๋งŽ์ด ์ฐพ์•„๋‚˜๊ฐ€์ž