Skip to content

Plugin loader keeps injected <script> tags in document.head after execution, causing unnecessary DOM and memory growth during long sessions #7388

@sahu-virendra-1908

Description

@sahu-virendra-1908

Description

While testing plugin loading in Music Blocks, I noticed that dynamically injected plugin <script> elements are never removed from document.head after they finish executing.

The issue occurs in:

js/utils/utils.js

inside the processPluginData plugin-loading flow.

Current implementation:

const script = document.createElement("script");
script.src = url;

document.head.appendChild(script);

The script element is appended to the DOM and executed, but it is never removed afterward.

This happens both for:

  • the main Blob-based plugin script
  • additional setup scripts created for plugin initialization

As a result, every plugin load leaves behind extra <script> nodes inside <head> for the lifetime of the session.

Expected Behavior

Temporary plugin loader <script> elements should be cleaned up after:

  • successful execution
  • failed loading
  • rejected initialization

The plugin should load normally without leaving unused DOM nodes behind.

Current Behavior

Every plugin load permanently adds new <script> tags to:

document.head

Reloading plugins multiple times in the same session causes:

  • unnecessary DOM growth
  • accumulation of unused script nodes
  • gradual memory increase during long-running sessions

Steps to Reproduce

  1. Open Music Blocks
  2. Load any plugin using the plugin menu
  3. Reload the same plugin multiple times
  4. Open DevTools → Elements
  5. Inspect:
<head>
  1. Observe that injected plugin <script> tags continue accumulating and are never removed

Root Cause

The dynamically created script elements are appended to the DOM but no cleanup happens after onload or onerror.

Current flow:

document.head.appendChild(script);

Missing cleanup:

document.head.removeChild(script);

Suggested Fix

Remove temporary script elements after execution completes:

script.onload = () => {
    URL.revokeObjectURL(url);
    document.head.removeChild(script); // ← ADD THIS
    resolve();
};
script.onerror = e => {
    URL.revokeObjectURL(url);
    document.head.removeChild(script); // ← ADD THIS
    reject(e);
};

The same cleanup should also be applied to the additional setup scripts created later in processPluginData.

Why This Matters

This issue does not usually break plugin functionality immediately, but repeated plugin loads in long-running sessions can gradually increase unnecessary DOM and memory usage.

Cleaning up temporary loader scripts keeps the runtime cleaner and prevents avoidable accumulation inside document.head.

Checklist

  • I have read and followed the project's code of conduct.
  • I have searched for similar issues before creating this one.
  • I have provided all the necessary information to understand and reproduce the issue.
  • I am willing to contribute to the resolution of this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions