How to Destroy a Wavesurfer.js Instance to Free Up Memory
Destroying a Wavesurfer.js instance properly is essential to prevent
memory leaks and free up browser resources when an audio visualization
component unmounts or is no longer needed. To completely tear down an
active instance, you must invoke the built-in destroy()
method on your Wavesurfer object, clear audio buffer references, and
remove any custom event listeners attached to the window or DOM.
Step 1: Call the
Built-in destroy() Method
Wavesurfer.js provides a native destroy() method that
handles core cleanup tasks automatically. Calling this method pauses
playback, stops audio decoding, removes internally attached DOM elements
(such as the canvas wave display), and detaches native event listeners
created by the library.
// Initialize Wavesurfer instance
const wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: '#4F46E5',
progressColor: '#818CF8',
url: '/path/to/audio.mp3',
});
// Tear down the instance when done
function cleanupWaveform() {
if (wavesurfer) {
wavesurfer.destroy();
}
}Step 2: Clear Custom Event Listeners and References
While wavesurfer.destroy() detaches Wavesurfer's
internal listeners, any custom event listeners or external state
bindings referencing the instance must be manually cleaned up.
Nullifying the variable reference allows JavaScript's garbage collector
to reclaim the allocated memory immediately.
// Remove custom global or DOM event listeners
window.removeEventListener('resize', handleResize);
// Nullify the variable reference for garbage collection
let wavesurferInstance = wavesurfer;
wavesurferInstance.destroy();
wavesurferInstance = null;Step 3: Lifecycle Integration in Modern Frameworks
When using Wavesurfer.js inside component-based frameworks like React or Vue, perform the destruction within the appropriate lifecycle cleanup hook to avoid memory leaks when components unmount.
React Integration
import { useEffect, useRef } from 'react';
import WaveSurfer from 'wavesurfer.js';
function AudioPlayer({ audioUrl }) {
const containerRef = useRef(null);
const wavesurferRef = useRef(null);
useEffect(() => {
if (!containerRef.current) return;
wavesurferRef.current = WaveSurfer.create({
container: containerRef.current,
url: audioUrl,
});
// Cleanup on unmount or URL change
return () => {
if (wavesurferRef.current) {
wavesurferRef.current.destroy();
wavesurferRef.current = null;
}
};
}, [audioUrl]);
return <div ref={containerRef} />;
}Vue 3 Integration
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import WaveSurfer from 'wavesurfer.js';
const waveformRef = ref(null);
let wavesurfer = null;
onMounted(() => {
wavesurfer = WaveSurfer.create({
container: waveformRef.value,
url: '/audio.mp3',
});
});
onUnmounted(() => {
if (wavesurfer) {
wavesurfer.destroy();
wavesurfer = null;
}
});
</script>
<template>
<div ref="waveformRef"></div>
</template>By explicitly calling destroy(), unbinding custom
listeners, and clearing object references, you ensure complete Web Audio
API and canvas memory reclamation across all browsers.