优化index的自动刷新,不占用内存了
This commit is contained in:
+102
-2
@@ -1341,9 +1341,54 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
let currentData = null;
|
||||
let lastRequestId = 0; // 防止过期响应覆盖新数据
|
||||
const tables = {};
|
||||
// ======= 趋势筛选(币对) =======
|
||||
let trendTable = null;
|
||||
|
||||
// 限长截断,减少前端长期持有历史数组导致的内存增长
|
||||
function trimDataInPlace(payload, maxLen = 2000) {
|
||||
const keepTail = (arr) => (Array.isArray(arr) && arr.length > maxLen) ? arr.slice(-maxLen) : arr;
|
||||
if (!payload || typeof payload !== 'object') return;
|
||||
|
||||
// 主/次周期K线
|
||||
payload.kline_data = keepTail(payload.kline_data);
|
||||
payload.element_kline_data = keepTail(payload.element_kline_data);
|
||||
|
||||
// MACD
|
||||
if (payload.macd) {
|
||||
payload.macd.macd = keepTail(payload.macd.macd);
|
||||
payload.macd.signal = keepTail(payload.macd.signal);
|
||||
payload.macd.histogram = keepTail(payload.macd.histogram);
|
||||
}
|
||||
if (payload.element_macd) {
|
||||
payload.element_macd.macd = keepTail(payload.element_macd.macd);
|
||||
payload.element_macd.signal = keepTail(payload.element_macd.signal);
|
||||
payload.element_macd.histogram = keepTail(payload.element_macd.histogram);
|
||||
}
|
||||
|
||||
// ATR
|
||||
payload.atr = keepTail(payload.atr);
|
||||
payload.element_atr = keepTail(payload.element_atr);
|
||||
|
||||
// 分形/线段/中枢/买卖点
|
||||
payload.bi_list = keepTail(payload.bi_list);
|
||||
payload.seg_list = keepTail(payload.seg_list);
|
||||
payload.zs_list = keepTail(payload.zs_list);
|
||||
payload.uncompleted_zs_list = keepTail(payload.uncompleted_zs_list);
|
||||
|
||||
payload.element_bi_list = keepTail(payload.element_bi_list);
|
||||
payload.element_seg_list = keepTail(payload.element_seg_list);
|
||||
payload.element_zs_list = keepTail(payload.element_zs_list);
|
||||
payload.element_uncompleted_zs_list = keepTail(payload.element_uncompleted_zs_list);
|
||||
|
||||
payload.trade_points = keepTail(payload.trade_points);
|
||||
payload.element_trade_points = keepTail(payload.element_trade_points);
|
||||
|
||||
// 移除可能保存的旧快照,避免重复持有
|
||||
delete payload.original_kline_data;
|
||||
delete payload.original_macd;
|
||||
}
|
||||
let trendDetailTable = null;
|
||||
let trendChart = null;
|
||||
|
||||
@@ -2230,6 +2275,7 @@
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
const requestId = ++lastRequestId; // 标记本次请求
|
||||
$.ajax({
|
||||
url: '/api/analyze',
|
||||
data: {
|
||||
@@ -2244,8 +2290,21 @@
|
||||
success: function(data) {
|
||||
// 隐藏加载图标
|
||||
$('#refreshLoadingSpinner').hide();
|
||||
|
||||
// 忽略过期响应
|
||||
if (requestId !== lastRequestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 截断数据以限制内存占用
|
||||
trimDataInPlace(data, 2000);
|
||||
|
||||
// 保存当前数据
|
||||
if (currentData) {
|
||||
// 覆盖前断开旧引用,帮助GC尽快回收
|
||||
delete currentData.original_kline_data;
|
||||
delete currentData.original_macd;
|
||||
}
|
||||
currentData = data;
|
||||
|
||||
// 检查和记录服务器返回的时区
|
||||
@@ -2267,6 +2326,34 @@
|
||||
// 初始化图表
|
||||
function initTradingView(symbol, timeframe) {
|
||||
try {
|
||||
// 在重新初始化前,尝试释放旧图表与系列资源,避免 GPU 内存累积
|
||||
try {
|
||||
if (tvWidget && tvWidget.state && tvWidget.state.isInitialized) {
|
||||
// 主图
|
||||
if (tvWidget.mainChart && typeof tvWidget.mainChart.remove === 'function') {
|
||||
tvWidget.mainChart.remove();
|
||||
}
|
||||
// 成交量
|
||||
if (tvWidget.volumeChart && typeof tvWidget.volumeChart.remove === 'function') {
|
||||
tvWidget.volumeChart.remove();
|
||||
}
|
||||
// 旧 MACD(若存在)
|
||||
if (tvWidget.macdChart && typeof tvWidget.macdChart.remove === 'function') {
|
||||
tvWidget.macdChart.remove();
|
||||
}
|
||||
// 新 ChanMACD(若存在)
|
||||
if (tvWidget.chanMacdChart && typeof tvWidget.chanMacdChart.remove === 'function') {
|
||||
tvWidget.chanMacdChart.remove();
|
||||
}
|
||||
// ATR
|
||||
if (tvWidget.atrChart && typeof tvWidget.atrChart.remove === 'function') {
|
||||
tvWidget.atrChart.remove();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('释放旧图表资源失败(可忽略):', e);
|
||||
}
|
||||
|
||||
console.log('初始化TradingView图表:', symbol, timeframe);
|
||||
|
||||
// 获取当前交易对的配置
|
||||
@@ -2337,8 +2424,9 @@
|
||||
console.log(`A股数据过滤: ${originalLength} -> ${candles.length} 条记录`);
|
||||
}
|
||||
|
||||
// 清除图表容器
|
||||
document.getElementById('tradingview_chart').innerHTML = '';
|
||||
// 清除图表容器(释放旧 DOM 与 Canvas)
|
||||
const chartRoot = document.getElementById('tradingview_chart');
|
||||
if (chartRoot) chartRoot.innerHTML = '';
|
||||
|
||||
// 重置图表对象
|
||||
tvWidget = {
|
||||
@@ -5683,6 +5771,18 @@
|
||||
tvWidget.macdChart = macdChart;
|
||||
tvWidget.chanMacdChart = chanMacdChart;
|
||||
tvWidget.state.isInitialized = true;
|
||||
// 注册窗口卸载时释放资源,避免GPU内存泄漏
|
||||
window.onbeforeunload = function() {
|
||||
try {
|
||||
if (tvWidget && tvWidget.state && tvWidget.state.isInitialized) {
|
||||
if (tvWidget.mainChart && typeof tvWidget.mainChart.remove === 'function') tvWidget.mainChart.remove();
|
||||
if (tvWidget.volumeChart && typeof tvWidget.volumeChart.remove === 'function') tvWidget.volumeChart.remove();
|
||||
if (tvWidget.macdChart && typeof tvWidget.macdChart.remove === 'function') tvWidget.macdChart.remove();
|
||||
if (tvWidget.chanMacdChart && typeof tvWidget.chanMacdChart.remove === 'function') tvWidget.chanMacdChart.remove();
|
||||
if (tvWidget.atrChart && typeof tvWidget.atrChart.remove === 'function') tvWidget.atrChart.remove();
|
||||
}
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
// 初始化默认EMA配置(仅在首次初始化时)
|
||||
if (movingAverages.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user