fix: Chrome 22G 内存泄漏 — renderEvaluation interval 竞态泄漏 + Chart.js 未 destroy

This commit is contained in:
hmo
2026-07-28 23:03:58 +08:00
parent 63b53f5c56
commit 62305cb062
+10 -5
View File
@@ -214,7 +214,7 @@ document.addEventListener('DOMContentLoaded', function() {
if (he) delete he.dataset.rendered;
}
if (name === 'health' && !healthRefreshInterval) {
healthRefreshInterval = setInterval(refreshHealth, 10000);
if (!healthRefreshInterval) healthRefreshInterval = setInterval(refreshHealth, 10000);
}
document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active'));
@@ -616,9 +616,12 @@ function renderMarket() {
// ── Evaluation Tab ──
let evalTimer = null;
let evalBusy = false;
function renderEvaluation() {
if (evalBusy) return;
evalBusy = true;
const el = document.getElementById('tab-evaluation');
if (evalTimer) clearInterval(evalTimer);
if (evalTimer) { clearInterval(evalTimer); evalTimer = null; }
fetchJSON('/api/tracking').then(data => {
const tracks = data.tracks || [];
const stats = data.stats || {};
@@ -709,8 +712,9 @@ function renderEvaluation() {
}).join('')}</tbody>
</table>
</div>`;
evalTimer = setInterval(renderEvaluation, 30000);
});
if (!evalTimer) evalTimer = setInterval(renderEvaluation, 30000);
evalBusy = false;
}).catch(() => { evalBusy = false; });
}
function triggerEval() {
const btn = document.querySelector('#tab-evaluation button');
@@ -797,8 +801,9 @@ async function openStock(code) {
const chartCanvas = document.getElementById('modalChart');
chartCanvas.innerHTML = '<canvas id="stockChart"></canvas>';
const ctx = document.getElementById('stockChart').getContext('2d');
if (window._stockChart) { try { window._stockChart.destroy(); } catch(e) {} window._stockChart = null; }
if (stockData.price_history && stockData.price_history.length > 1) {
new Chart(ctx, {
window._stockChart = new Chart(ctx, {
type: 'line',
data: {
labels: stockData.price_history.map(p => p.date),