Skip to main content
Mediabunny is designed for high performance from the ground up. This guide covers best practices and optimization techniques to get the most out of the library.

Core design principles

Mediabunny’s architecture is built around several key performance principles:

Tree-shakable

Only bundle what you use. Format-specific code is automatically excluded when not imported.

Pipelined

Streaming design keeps memory usage constant regardless of file size.

Lazy evaluation

Work is deferred until needed, minimizing unnecessary processing.

Hardware accelerated

WebCodecs API provides native hardware encoding/decoding when available.

Tree-shaking benefits

Mediabunny is highly modular. Only the code you import gets bundled:
Only import the formats you actually need to minimize bundle size. If you only work with MP4 files, there’s no reason to include WebM or Matroska support.

Pipelined design

Mediabunny uses a pipelined architecture that processes data in a streaming fashion: Each stage:
  • Processes data as it arrives
  • Maintains a small buffer
  • Applies backpressure when needed
  • Runs in parallel with other stages
Benefits:
  • Memory usage stays constant
  • Large files can be processed
  • Encoding starts immediately
  • No waiting for entire file

Respecting backpressure

Backpressure prevents memory buildup when downstream stages can’t keep up:
Always await media source add() calls. Not doing so can cause unbounded memory growth and encoder queue overflow.

Hardware acceleration

Mediabunny leverages the WebCodecs API for hardware-accelerated encoding and decoding:
In most cases, leave hardwareAcceleration at 'no-preference' and let the browser decide. Browsers are generally good at choosing the best encoder.
Hardware acceleration availability:
  • Desktop Chrome/Edge: Excellent support for AVC, HEVC, VP9, AV1
  • Desktop Safari: Good support for AVC, HEVC
  • Desktop Firefox: Software-only in most cases
  • Mobile browsers: Generally good hardware support

Checking encoder support

Before creating an encoder, check if hardware acceleration is available:

Memory optimization

Close resources promptly

Always close VideoFrames, VideoSamples, and AudioSamples when done:
Failing to close samples causes memory leaks. VideoFrames hold GPU memory that must be explicitly released.

Close sources early

Close media sources as soon as you’re done adding data:
Benefits:
  • Reduces packet buffering
  • Allows muxer to optimize other tracks
  • Lowers overall memory usage

Use canvas pooling

When using CanvasSink, enable canvas pooling to reuse canvases:
For sequential iteration, poolSize: 1 is optimal:

Stream large files

Use streaming I/O for large files:
StreamTarget automatically triggers a browser download as data is written, keeping memory usage low.

Encoding/decoding optimization

Choose appropriate bitrates

Use quality presets or calculate bitrates based on resolution:
Rough bitrate guidelines (AVC, 30fps):
  • 480p: 1-2 Mbps
  • 720p: 2-5 Mbps
  • 1080p: 5-10 Mbps
  • 4K: 15-30 Mbps

Adjust key frame interval

Shorter intervals improve seeking but increase size:
Trade-offs:
  • Shorter interval: Better seeking, larger file size
  • Longer interval: Worse seeking, smaller file size
When using multiple video tracks, use the same keyFrameInterval for all tracks to ensure aligned key frames.

Optimize for real-time

For real-time encoding (screen recording, webcam):

Batch audio samples

When using AudioSampleSource, batch small samples when possible:

Reading optimization

Use metadata-only packets

When you only need packet metadata:
Benefits:
  • Faster retrieval
  • Lower memory usage
  • Reduced I/O

Use sparse sampling efficiently

For non-sequential frame access, use samplesAtTimestamps:

Exit iterations early

Use break to exit early and clean up resources:

Skip decoding when possible

If you don’t need decoded data, use EncodedPacketSink:

Bundle size optimization

Import only what you need

Use format-specific imports

Lazy-load less common formats

For formats used rarely, consider dynamic imports:

Performance monitoring

Track encoding progress

Monitor output progress

Measure decode performance

Common performance pitfalls

Problem: Ignoring backpressure causes memory buildup
Problem: Memory leaks from unclosed VideoFrames/AudioData
Problem: Entire file kept in memory
Problem: Unnecessarily large bundle size
Problem: Inefficient decoding of same packets

Benchmarking tips

1

Test with realistic data

Use actual video files and canvas content, not synthetic test patterns.
2

Test on target browsers

Performance varies significantly between browsers and platforms.
3

Measure end-to-end

Include all operations (reading, decoding, processing, encoding, writing).
4

Monitor memory

Use browser DevTools to check memory usage over time.
5

Test with different codecs

Some codecs are faster than others on specific hardware.

See also