fix: 修复主站自动刷新内存泄漏,并完善 chan_tv 图表体验

主站重建前完整 dispose、去掉重复 sync 监听,自动刷新默认增量更新;顺带消除首屏重复 analyze、复用 ChanMACD,以及全版 TV 指标/未完成中枢/布局本地缓存。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-06 16:09:48 +08:00
co-authored by Cursor
parent 6b0f3b5837
commit 9f1e7361b6
14 changed files with 457 additions and 669 deletions
+37 -7
View File
@@ -88,15 +88,13 @@ $(document).ready(function() {
.always(function() {
loadAStockSymbols();
startAStockStatusUpdater();
// A 股:metadata 完成后再拉数(下方不再重复 updateChart
setTimeout(function() {
updateChart();
}, 300);
});
} else {
setTimeout(function() {
updateChart();
}, 500);
}
// 加密货币:统一在文末单次 updateChart,避免重复请求
// 初始化交易对下拉菜单
$('#symbol').val('BTC/USDT:USDT');
@@ -245,6 +243,7 @@ $(document).ready(function() {
// 自动刷新相关变量
let autoRefreshTimer = null;
let nextRefreshTime = null;
let autoRefreshTick = 0;
// 初始化自动刷新功能
function initAutoRefresh() {
// 监听自动刷新勾选框变化
@@ -281,12 +280,18 @@ function startAutoRefresh() {
updateNextRefreshTimeDisplay();
// 启动定时器
autoRefreshTick = 0;
autoRefreshTimer = setInterval(function() {
// 更新结束时间为当前时间
updateEndTimeToNow();
// 刷新图表
updateChart();
// 多数周期增量更新;每隔若干次全量重建以刷新笔/段/中枢(dispose 已防泄漏)
autoRefreshTick += 1;
const fullRebuild = (autoRefreshTick % 6) === 0;
updateChart({
fromAutoRefresh: true,
incremental: !fullRebuild
});
// 更新下次刷新时间
nextRefreshTime = new Date(Date.now() + intervalMs);
@@ -512,7 +517,7 @@ function updateFractalTables() {
}
// 刷新图表并更新表格
function refreshChart(data) {
function refreshChart(data, options) {
// 检查是否接收到数据
if (!data) {
console.error('未收到数据,无法刷新图表');
@@ -522,6 +527,31 @@ function refreshChart(data) {
if (data.element_timeframe) {
$('#elementTimeframe').val(data.element_timeframe);
}
options = options || {};
const preferIncremental = !!options.incremental;
const chartsReady = tvWidget && tvWidget.state && tvWidget.state.isInitialized && tvWidget.mainChart;
// 自动刷新:增量更新,避免每次销毁/重建 Lightweight Charts
if (preferIncremental && chartsReady) {
try {
if (tvWidget.mainChart) {
try {
window._pendingRestoreView = captureChartViewState(tvWidget.mainChart);
} catch (e) {
window._pendingRestoreView = null;
}
}
updateTradingViewData();
updateTables(data);
if (currentData && currentData.ema52_dict) {
updateEMA52Display(currentData);
}
return;
} catch (e) {
console.warn('增量刷新失败,回退全量重建:', e);
}
}
// 保存当前缩放(barSpacing)和滚动位置(scrollPosition)到 window
// tvWidget 会在 initTradingView 内被重建,所以必须存到 window 上