How to Programmatically Destroy a Web‑Tracing Instance: Complete Cleanup Guide
Call the destroy() method on your WebTracing instance to clear timers, remove event listeners, close WebSocket connections, and flush pending telemetry.
When working with the m-cheng-web/web-tracing library, properly terminating your tracing session is critical to prevent memory leaks and ensure all telemetry data reaches your backend. The library maintains active timers, DOM event listeners, and persistent network connections that continue running until explicitly stopped. Understanding how to programmatically destroy a web-tracing instance ensures your application can cleanly shut down tracing during SPA navigation, user logout, or test teardown without leaving orphaned resources.
Why You Must Explicitly Destroy Web‑Tracing Instances
The Web‑Tracing library creates a singleton-style object that registers listeners, starts a background sampler, and opens a WebSocket (or HTTP) connection to the tracing backend. Without proper cleanup:
- Interval timers and
requestAnimationFramecallbacks continue firing indefinitely - Event listeners attached via
window.addEventListeneranddocument.addEventListeneraccumulate - Open WebSocket or EventSource connections remain active, consuming network resources
- Internal buffers retain references, preventing garbage collection
Calling destroy() is the only officially supported method to release these resources and allow the JavaScript engine to reclaim memory.
How the destroy() Method Works Internally
In src/web-tracing.ts, the destroy() method implements a systematic teardown sequence. The implementation ensures that every component registered during initialization is properly reversed.
Stopping the Background Sampler
The tracing instance starts a sampling loop via this._sampler.start() during construction. During destruction, destroy() calls this._sampler.stop() (implemented in src/sampler.ts) to cancel the interval or requestAnimationFrame loop immediately.
Removing Registered Event Listeners
The instance maintains an internal registry this._registeredListeners containing all DOM events subscribed during initialization. The destroy() method iterates this collection and invokes removeEventListener for each entry, ensuring no tracing-related handlers remain attached to window or document.
Closing Network Connections
If the instance established a WebSocket connection (this._socket), the method executes socket.close() to terminate the transport gracefully. This step also closes any active EventSource or fetch-based long-polling connections opened for trace submission.
Flushing Pending Telemetry
Before clearing state, destroy() executes await this._flushPending() to transmit any buffered spans to the configured endpoint. This asynchronous flush ensures no trace data is lost during shutdown, returning a Promise that resolves once the network operation completes.
Code Examples for Destroying Web‑Tracing
Class-Based Instance
When instantiating WebTracing directly, store the reference and await the cleanup:
import { WebTracing } from "web-tracing";
const tracing = new WebTracing({
endpoint: "https://tracing.example.com/collect",
sampleRate: 0.5,
});
tracing.startSpan("page-load");
// Later, when tracing is no longer needed:
await tracing.destroy();
After destroy() resolves, the tracing variable holds no active timers, listeners, or connections.
Default Singleton
If using the default exported singleton from src/index.ts, invoke destroy directly on the imported object:
import tracing from "web-tracing";
// Application logic here...
await tracing.destroy();
Key Source Files in web-tracing
Understanding the source structure helps debug cleanup issues:
src/web-tracing.ts– CoreWebTracingclass containing the constructor,start,destroy, and internal helper methods such as_flushPending()src/sampler.ts– ImplementsSampler.start()andSampler.stop()methods that control the background collection loopsrc/index.ts– Public entry point exporting both the class and default singleton instance
These files collectively define the lifecycle management that makes programmatic destruction possible.
Summary
- The WebTracing class exposes a
destroy()method that performs complete cleanup of the tracing instance - Timers and samplers are stopped via
this._sampler.stop()to prevent further execution - Event listeners are removed by iterating
this._registeredListenersand callingremoveEventListener - Network connections are closed through
socket.close()and similar transport-specific methods - Pending data is flushed asynchronously via
_flushPending()before returning - After destruction, the instance can be garbage collected and the library safely reinitialized
Frequently Asked Questions
What happens if I don't call destroy() on my WebTracing instance?
If you fail to call destroy(), the instance continues running background timers, maintaining DOM event listeners, and keeping WebSocket connections open. This leads to memory leaks in single-page applications and can cause duplicate data submission if you attempt to create a new instance without cleaning up the old one.
Can I restart tracing after calling destroy()?
Yes, but you must create a fresh instance. Once destroy() completes, the original instance becomes inert and cannot be restarted. Instantiate new WebTracing(config) again to begin collecting traces, which is particularly useful in test suites or when switching between user contexts.
Is the destroy() method synchronous or asynchronous?
The destroy() method is asynchronous and returns a Promise. It awaits the completion of this._flushPending() to ensure all buffered telemetry reaches the backend before resolving. Always use await tracing.destroy() or handle the returned Promise to guarantee cleanup completes before proceeding.
Does destroy() remove all trace data stored locally?
The destroy() method flushes pending spans to the server but does not explicitly wipe historical data from browser storage mechanisms like localStorage or IndexedDB if the library uses them. It primarily concerns runtime resources—timers, listeners, and connections—rather than persistent storage cleanup.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →