Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve the memory leak problem when creating multiple HLJS instances (#4086) #4095

Merged
merged 3 commits into from
Aug 22, 2024

Conversation

immccn123
Copy link
Contributor

@immccn123 immccn123 commented Aug 19, 2024

Fixes the memory leak problem mentioned in the above issue, using #4086 (comment) as the solution.

Resolves #4086.

Changes

The event listener is added to the window only when highlightAll() is called, and the listener will be removed by itself when DOM content is loaded.

Checklist

  • Added markup tests, or they don't apply here because...
  • Updated the changelog at CHANGES.md

src/highlight.js Outdated
function boot() {
// if a highlight was requested before DOM was loaded, do now
highlightAll();
window.removeEventListener('DOMContentLoaded', boot, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the thinking here? Is this type of cleanup truly necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cleanup might only matter in rare cases, like when an hljs instance is used just once and highlightAll is called before DOMContentLoaded. In such a scenario, the instance would stay in memory, unable to be released. If this corner case isn't a concern, the cleanup is likely unnecessary.

If this contradicts the core philosophy, the cleanup can be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just going to call it unnecessary -- unless you have some docs (from MDN or such) that says this is somehow best practice... I've seen tons of onload hooks like this over the years but never code to unwind a single-use event listner afterwards - seems a browser concern... if the browser knows that event that just fired can never be fired again on the same page it could do the cleanup itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your point. While the event could technically be triggered using window.dispatchEvent(new Event("DOMContentLoaded")), which isn't common practice, this means the browser wouldn’t automatically handle the cleanup. However, another approach to ensure the listener is only triggered once and automatically cleaned up is to use window.addEventListener(..., { once: true }). Is this one better, or just remove the cleanup?

Would you prefer switching to { once: true }, or should we remove the cleanup entirely?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event

I find zero examples of once being suggested. Lets just remove the cleanup.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification and patience! I've removed the cleanup.

@joshgoebel
Copy link
Member

Awesome, now can you just add an entry to CHANGES and then I think this is good to merge.

Copy link

Build Size Report

Changes to minified artifacts in /build, after gzip compression.

3 files changed

Total change -44 B

View Changes
file base pr diff
es/core.min.js 8.2 KB 8.18 KB -17 B
es/highlight.min.js 8.2 KB 8.18 KB -17 B
highlight.min.js 8.23 KB 8.22 KB -10 B

@immccn123
Copy link
Contributor Author

Changelog entry has been added as requested. Thanks for your guidance throughout this process!

Copy link

Build Size Report

Changes to minified artifacts in /build, after gzip compression.

3 files changed

Total change -45 B

View Changes
file base pr diff
es/core.min.js 8.2 KB 8.18 KB -17 B
es/highlight.min.js 8.2 KB 8.18 KB -17 B
highlight.min.js 8.23 KB 8.22 KB -11 B

@joshgoebel joshgoebel merged commit 19819d5 into highlightjs:main Aug 22, 2024
19 checks passed
@erha19
Copy link

erha19 commented Sep 18, 2024

@immccn123 hi, is there any new version for this fix?

@urmauur
Copy link

urmauur commented Nov 25, 2024

@immccn123 hi, is there any new version for this fix?

11.10.0...main

i think on 11.10.0

@joshgoebel
Copy link
Member

Fixed in 11.11.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Memory leaks when using newInstance to create multiple hljs instances
4 participants