Fix memory leaks in dashboard: clear iframe src on dialog close, limit toast queue, add cleanup destroy method

This commit is contained in:
mahdahar 2026-03-05 16:18:43 +07:00
parent a65feb0495
commit 1ea1fd4d0e
2 changed files with 44 additions and 2 deletions

View File

@ -61,7 +61,7 @@ class Filters extends BaseFilters
'after' => [
'pagecache', // Web Page Caching
'performance', // Performance Metrics
'toolbar', // Debug Toolbar
#'toolbar', // Debug Toolbar
],
];

View File

@ -7,6 +7,10 @@ document.addEventListener('alpine:init', () => {
isLoading: false,
counters: { Pend: 0, Coll: 0, Recv: 0, Inc: 0, Fin: 0, Total: 0 },
// Toast queue to prevent DOM accumulation
_toastQueue: [],
_maxToasts: 3,
selectedPrinter: localStorage.getItem('selectedPrinter') || 'zebracs2',
initSelectedPrinter() {
@ -224,6 +228,7 @@ document.addEventListener('alpine:init', () => {
closeSampleDialog() {
this.isDialogSampleOpen = false;
this.item = null;
this.item = [];
},
fetchItem(accessnumber) {
@ -489,6 +494,9 @@ document.addEventListener('alpine:init', () => {
this.previewItem = null;
this.previewAccessnumber = null;
this.isPreviewIframeLoaded = false;
// Clear iframe src to release memory
const iframe = this.$refs.previewIframe;
if (iframe) iframe.src = 'about:blank';
},
getPreviewUrl() {
if(this.previewAccessnumber != null) {
@ -563,6 +571,9 @@ document.addEventListener('alpine:init', () => {
this.engResultItem = null;
this.isEngResultIframeLoaded = false;
this.isCreatingEngResult = false;
// Clear iframe src to release memory
const iframe = this.$refs.engResultIframe;
if (iframe) iframe.src = 'about:blank';
},
getEngResultUrl() {
@ -602,11 +613,42 @@ document.addEventListener('alpine:init', () => {
},
showToast(message, type = 'success') {
// Limit concurrent toasts to prevent DOM accumulation
if (this._toastQueue.length >= this._maxToasts) {
const oldToast = this._toastQueue.shift();
if (oldToast && oldToast.parentNode) oldToast.remove();
}
const toast = document.createElement('div');
toast.className = `alert alert-${type} fixed top-4 right-4 z-50`;
toast.innerHTML = `<i class="fa ${type === 'error' ? 'fa-times-circle' : 'fa-check-circle'}"></i> ${message}`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 2000);
this._toastQueue.push(toast);
setTimeout(() => {
toast.remove();
const index = this._toastQueue.indexOf(toast);
if (index > -1) this._toastQueue.splice(index, 1);
}, 2000);
},
destroy() {
// Clear large data arrays to free memory
this.list = [];
this.filtered = [];
this.sorted = [];
this.paginated = [];
this.auditData = null;
this._cachedAuditEvents = [];
this.item = null;
this.previewItem = null;
this.engResultItem = null;
// Clear any open dialogs and their iframe references
if (this.$refs.previewIframe) this.$refs.previewIframe.src = 'about:blank';
if (this.$refs.engResultIframe) this.$refs.engResultIframe.src = 'about:blank';
// Clear any remaining toasts
this._toastQueue.forEach(t => { if (t.parentNode) t.remove(); });
this._toastQueue = [];
},
}));
});