Lesson 04-Bun.js Advanced Features

Performance Optimization

JIT Compilation and Performance Tuning

JIT Compilation Optimization Mechanisms:

// Enable JIT compilation optimization (enabled by default)
Bun.env.BUN_ENABLE_JIT = '1'  // Explicitly enable (default value)

// Performance-critical code example
function calculatePrimes(max) {
  const primes = []
  for (let i = 2; i <= max; i++) {
    let isPrime = true
    for (let j = 2; j * j <= i; j++) {
      if (i % j === 0) {
        isPrime = false
        break
      }
    }
    if (isPrime) primes.push(i)
  }
  return primes
}

// Warm up JIT compiler
for (let i = 0; i < 1000; i++) {
  calculatePrimes(1000)  // Warm up hot code
}

// Actual performance test
console.time('prime-calculation')
calculatePrimes(100000)  // Execution after JIT optimization
console.timeEnd('prime-calculation')

Performance Tuning Parameters:

# Runtime environment variable configuration
BUN_ENABLE_JIT=1          # Enable JIT (default)
BUN_GC_INTERVAL=1000      # GC interval (milliseconds)
BUN_MEMORY_LIMIT=4GB      # Memory limit

Memory Management and Garbage Collection

Memory Management Strategies:

// Memory usage monitoring
setInterval(() => {
  const memoryUsage = process.memoryUsage()
  console.log({
    rss: `${(memoryUsage.rss / 1024 / 1024).toFixed(2)}MB`,
    heapUsed: `${(memoryUsage.heapUsed / 1024 /じ1024).toFixed(2)}MB`,
    heapTotal: `${(memoryUsage.heapTotal / 1024 / 1024).toFixed(2)}MB`
  })
}, 5000)

// Large data processing
function processLargeData() {
  // Use streaming instead of full loading
  const file = Bun.file('large-data.json')
  const stream = file.stream()

  let data = ''
  for await (const chunk of stream) {
    data += chunk
    // Process data in batches
    if (data.length > 10 * 1024 * 1024) {  // 10MB batches
      processDataChunk(data)
      data = ''
    }
  }
  if (data) processDataChunk(data)
}

// Manually trigger GC (use with caution)
if (globalThis.Bun) {
  Bun.gc()  // Explicitly trigger garbage collection
}

Event Loop Optimization

Event Loop Scheduling Strategies:

// Microtask optimization example
async function processBatch(tasks) {
  // Split large tasks into microtask batches
  const BATCH_SIZE = 100
  for (let i = 0; i < tasks.length; i += BATCH_SIZE) {
    const batch = tasks.slice(i, i + BATCH_SIZE)
    await Promise.all(batch.map(task => 
      Promise.resolve().then(() => task())  // Microtask queue
    ))
  }
}

// Macrotask scheduling optimization
function scheduleMacroTask(task) {
  // Use setImmediate instead of setTimeout(fn, 0)
  if (typeof setImmediate === 'function') {
    setImmediate(task)
  } else {
    setTimeout(task, 0)
  }
}

// I/O-intensive task optimization
async function handleConcurrentRequests(requests) {
  // Use Promise.allSettled for parallel processing
  const results = await Promise.allSettled(
    requests.map(req => fetch(req.url, req.options))
  )
  // Process results...
}

Concurrency and Parallel Processing

Advanced Worker Threads Usage:

// Main thread code
import { Worker, MessageChannel } from 'bun'

function runInWorker(taskFn, ...args) {
  return new Promise((resolve, reject) => {
    const worker = new Worker(new URL(import.meta.url).pathname, {
      type: 'module',
      workerData: { taskFn: taskFn.toString(), args }
    })

    worker.onmessage = (e) => resolve(e.data)
    worker.onerror = (e) => reject(e.error)
  })
}

// worker.js (in the same directory)
if (import.meta.main) {
  const { parentPort, workerData } = require('worker_threads')
  const { taskFn, args } = workerData

  // Dynamically execute task function
  const task = new Function('return ' + taskFn)()
  const result = task(...args)
  parentPort.postMessage(result)
}

// Usage example
const result = await runInWorker(
  (a, b) => a + b,  // Task function
  10, 20            // Arguments
)

Shared Memory Optimization:

// Use SharedArrayBuffer for inter-thread shared memory
const sharedBuffer = new SharedArrayBuffer(1024)
const sharedArray = new Int32Array(sharedBuffer)

// Main thread writes data
sharedArray[0] = 42

// Worker thread reads data
const worker = new Worker(new URL(import.meta.url).pathname)
worker.postMessage(sharedBuffer)

Caching Strategy Implementation

Multi-Level Cache System Design:

// Memory cache + disk cache implementation
class MultiLevelCache {
  constructor() {
    this.memoryCache = new Map()
    this.diskCache = new Bun.FileSystemCache('./cache')
  }

  async get(key) {
    // 1. Check memory cache
    if (this.memoryCache.has(key)) {
      return this.memoryCache.get(key)
    }

    // 2. Check disk cache
    const diskData = await this.diskCache.get(key)
    if (diskData) {
      // Backfill memory cache
      this.memoryCache.set(key, diskData)
      return diskData
    }

    return null
  }

  async set(key, value, ttl = 60) {
    // 1. Set memory cache
    this.memoryCache.set(key, value)

    // 2. Set disk cache
    await this.diskCache.set(key, value, { ttl })
  }
}

// Usage example
const cache = new MultiLevelCache()
await cache.set('user:1', { name: 'Bun User' })
const user = await cache.get('user:1')

Advanced Module System

ESM and CommonJS Mixed Usage

Mixed Module Loading Strategy:

// Dynamically load different module systems
async function loadModule(modulePath) {
  if (modulePath.endsWith('.mjs') || 
      (await isESMModule(modulePath))) {
    // ESM module
    return import(modulePath)
  } else {
    // CommonJS module
    return require(modulePath)
  }
}

// Detect module type
async function isESMModule(modulePath) {
  try {
    const content = await Bun.file(modulePath).text()
    return content.includes('export') || content.includes('import')
  } catch {
    return false
  }
}

// Usage example
const module = await loadModule('./dynamic-module')

Custom Module Loader

Implementing a Custom Loader:

// Register custom module loader
Bun.runtime.registerModuleLoader('custom', {
  resolve(specifier, context, defaultResolve) {
    if (specifier.startsWith('custom:')) {
      return {
        url: specifier.replace('custom:', 'file://'),
        format: 'custom'
      }
    }
    return defaultResolve(specifier, context)
  },

  load(url, context, defaultLoad) {
    if (url.protocol === 'file:') {
      const content = Bun.file(url.pathname).text()
      return {
        format: 'custom',
        source: transformCustomFormat(content)
      }
    }
    return defaultLoad(url, context)
  }
})

// Use custom module
import customModule from 'custom:./module.custom'

Module Cache Optimization

Cache Control Strategy:

// Dynamic module cache control
const moduleCache = new Map()

async function getModule(modulePath) {
  // 1. Check cache
  if (moduleCache.has(modulePath)) {
    return moduleCache.get(modulePath)
  }

  // 2. Load module
  const module = await import(modulePath)

  // 3. Cache module
  moduleCache.set(modulePath, module)

  // 4. Set cache expiration (optional)
  if (shouldInvalidateCache(modulePath)) {
    setTimeout(() => {
      moduleCache.delete(modulePath)
    }, 60 * 1000)  // 1-minute cache
  }

  return module
}

// Disable cache in development environment
if (process.env.NODE_ENV === 'development') {
  Bun.runtime.setModuleCacheEnabled(false)
}

Module Resolution Mechanism

Custom Resolution Logic:

// Override default module resolution
Bun.runtime.setModuleResolver((specifier, parentURL) => {
  // 1. Handle special protocols
  if (specifier.startsWith('app:')) {
    return {
      url: `file://${path.join(__dirname, specifier.replace('app:', ''))}`,
      format: 'commonjs'
    }
  }

  // 2. Handle aliases
  const aliases = {
    '@utils': './src/utils',
    '@components': './src/components'
  }

  for (const [alias, prefix] of Object.entries(aliases)) {
    if (specifier.startsWith(alias)) {
      return {
        url: `file://${path.join(__dirname, prefix, specifier.replace(alias, ''))}`,
        format: 'esm'
      }
    }
  }

  // 3. Default resolution
  return Bun.runtime.defaultModuleResolver(specifier, parentURL)
})

Module Performance Optimization

Module Loading Optimization Techniques:

// 1. Preload critical modules
Bun.preloadModules([
  './core/utils.js',
  './core/services.js'
])

// 2. Lazy-load non-critical modules
const heavyModule = await import('./heavy-module.js')

// 3. Module splitting strategy
// Split large modules into smaller ones
import { featureA } from './features/feature-a.js'
import { featureB } from './features/feature-b.js'

// 4. Use Tree Shaking
// Ensure ESM exports are static
export function usedFunction() {}
export function unusedFunction() {}  // Will be removed by Tree Shaking

Advanced Network Programming

WebSocket Implementation

High-Performance WebSocket Server:

import { serve } from 'bun'

const server = serve({
  port: 8080,
  fetch(request) {
    if (request.headers.get('upgrade') === 'websocket') {
      // Upgrade to WebSocket connection
      const { socket, response } = Bun.upgradeWebSocket(request)

      // WebSocket event handling
      socket.onopen = () => {
        console.log('WebSocket connected')
        socket.send('Welcome to Bun WebSocket!')
      }

      socket.onmessage = (event) => {
        console.log('Received:', event.data)
        socket.send(`Echo: ${event.data}`)
      }

      socket.onclose = () => {
        console.log('WebSocket disconnected')
      }

      return response
    }

    // Handle regular HTTP requests
    return new Response('HTTP Server')
  }
})

console.log('Server running on ws://localhost:8080')

WebSocket Client Implementation:

const socket = new Bun.WebSocket('ws://localhost:8080')

socket.onopen = () => {
  console.log('Connected to server')
  socket.send('Hello Server!')
}

socket.onmessage = (event) => {
  console.log('Received:', event.data)
}

socket.onclose = () => {
  console.log('Connection closed')
}

// Send binary data
const buffer = new Uint8Array([1, 2, 3])
socket.send(buffer)

HTTP/2 and HTTP/3 Support

HTTP/2 Server Configuration:

import { serve } from 'bun'

const server = serve({
  port: 443,
  https: {
    certFile: './cert.pem',
    keyFile: './key.pem'
  },
  // Enable HTTP/2
  http2: true
})

console.log('HTTP/2 Server running on https://localhost:443')

Experimental HTTP/3 Support:

// Note: Requires Bun's experimental feature support
import { serve } from 'bun'

const server = serve({
  port: 443,
  quic: {  // HTTP/3 based on QUIC protocol
    certFile: './cert.pem',
    keyFile: './key.pem'
  }
})

console.log('HTTP/3 Server running (experimental)')

Proxy Server Implementation

HTTP Reverse Proxy Example:

import { serve } from 'bun'

const proxy = serve({
  port: 8080,
  fetch(request) {
    // Parse target URL
    const targetUrl = new URL(request.url)
    targetUrl.hostname = 'api.example.com'
    targetUrl.port = '443'
    targetUrl.protocol = 'https:'

    // Forward request
    return fetch(targetUrl.toString(), {
      method: request.method,
      headers: request.headers,
      body: request.body
    })
  }
})

console.log('Reverse Proxy running on http://localhost:8080')

Advanced Proxy Features:

// Request/response transformation proxy
serve({
  fetch(request) {
    // 1. Modify request
    const modifiedRequest = new Request(request, {
      headers: new Headers({
        'X-Forwarded-For': request.headers.get('x-forwarded-for') || '127.0.0.1'
      })
    })

    // 2. Forward request
    return fetch('https://target-api.com', {
      method: modifiedRequest.method,
      headers: modifiedRequest.headers,
      body: modifiedRequest.body
    })
    .then(async response => {
      // 3. Modify response
      const modifiedResponse = new Response(response.body, {
        status: response.status,
        headers: new Headers({
          'X-Proxy-By': 'Bun Proxy',
          ...Object.fromEntries(response.headers)
        })
      })

      return modifiedResponse
    })
  }
})

Network Protocol Parsing

TCP Server Implementation:

import { TCP } from 'bun'

const tcp = new TCP({
  port: 8080,
  host: '0.0.0.0'
})

tcp.on('connection', (socket) => {
  console.log('New TCP connection')

  socket.on('data', (data) => {
    console.log('Received:', data.toString())
    socket.write('Echo: ' + data)
  })

  socket.on('close', () => {
    console.log('Connection closed')
  })
})

console.log('TCP Server running on tcp://localhost:8080')

UDP Server Example:

import { UDP } from 'bun'

const udp = new UDP({
  port: 8080
})

udp.on('message', (message, remote) => {
  console.log(`Received from ${remote.address}:${remote.port}:`, message.toString())

  // Reply to message
  udp.send('Echo: ' + message, remote.port, remote.address)
})

console.log('UDP Server running on udp://localhost:8080')

Network Performance Optimization

High-Performance Network Programming Techniques:

// 1. Connection pool management
class ConnectionPool {
  constructor(maxConnections = 10) {
    this.pool = []
    this.maxConnections = maxConnections
  }

  async getConnection(url) {
    if (this.pool.length > 0) {
      return this.pool.pop()
    }

    if (this.pool.length < this.maxConnections) {
      return this.createConnection(url)
    }

    // Wait for connection release
    return new Promise(resolve => {
      const interval = setInterval(() => {
        if (this.pool.length > 0) {
          clearInterval(interval)
          resolve(this.pool.pop())
        }
      }, 100)
    })
  }

  async createConnection(url) {
    const response = await fetch(url)
    return {
      response,
      release: () => this.pool.push(this)
    }
  }
}

// 2. Batch request processing
async function batchRequests(urls, batchSize = 10) {
  const results = []
  for (let i = 0; i < urls.length; i += batchSize) {
    const batch = urls.slice(i, i + batchSize)
    const batchResults = await Promise.all(
      batch.map(url => fetch(url).then(res => res.json()))
    )
    results.push(...batchResults)
  }
  return results
}

// 3. Zero-copy data transfer
async function sendFile(socket, filePath) {
  const file = Bun.file(filePath)
  const stream = file.stream()

  for await (const chunk of stream) {
    socket.write(chunk)
  }
}
Share your love