Skip exchange PnL sync on hub iframe soft nav to fix slow records tab.
Remove hover prefetch and mark soft-nav fetches so Gate/OKX render pages from local DB without blocking on exchange history sync. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<script src="/static/instance_theme.js?v=15"></script>
|
<script src="/static/instance_theme.js?v=16"></script>
|
||||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
||||||
<script src="/static/account_risk_badge.js?v=3"></script>
|
<script src="/static/account_risk_badge.js?v=3"></script>
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ from order_monitor_display_lib import (
|
|||||||
)
|
)
|
||||||
from wechat_notify_lib import build_wechat_rs_level_message, send_wechat_webhook
|
from wechat_notify_lib import build_wechat_rs_level_message, send_wechat_webhook
|
||||||
from hub_auth import request_allowed as hub_request_allowed
|
from hub_auth import request_allowed as hub_request_allowed
|
||||||
|
from instance_nav_lib import request_is_hub_soft_nav
|
||||||
from hub_volume_rank_lib import resolve_daily_volume_rank
|
from hub_volume_rank_lib import resolve_daily_volume_rank
|
||||||
from history_window_lib import (
|
from history_window_lib import (
|
||||||
PRESET_CUSTOM,
|
PRESET_CUSTOM,
|
||||||
@@ -6725,7 +6726,7 @@ def render_main_page(page="trade"):
|
|||||||
for o in raw_order_list:
|
for o in raw_order_list:
|
||||||
order_list.append(enrich_order_item(row_to_dict(o), current_capital))
|
order_list.append(enrich_order_item(row_to_dict(o), current_capital))
|
||||||
exchange_pnl_sync = {}
|
exchange_pnl_sync = {}
|
||||||
if exchange_private_api_configured():
|
if exchange_private_api_configured() and not request_is_hub_soft_nav():
|
||||||
try:
|
try:
|
||||||
exchange_pnl_sync = sync_trade_records_from_exchange(conn) or {}
|
exchange_pnl_sync = sync_trade_records_from_exchange(conn) or {}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<script src="/static/instance_theme.js?v=15"></script>
|
<script src="/static/instance_theme.js?v=16"></script>
|
||||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
||||||
<script src="/static/account_risk_badge.js?v=3"></script>
|
<script src="/static/account_risk_badge.js?v=3"></script>
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ from order_monitor_display_lib import (
|
|||||||
)
|
)
|
||||||
from wechat_notify_lib import build_wechat_rs_level_message, send_wechat_webhook
|
from wechat_notify_lib import build_wechat_rs_level_message, send_wechat_webhook
|
||||||
from hub_auth import request_allowed as hub_request_allowed
|
from hub_auth import request_allowed as hub_request_allowed
|
||||||
|
from instance_nav_lib import request_is_hub_soft_nav
|
||||||
from hub_volume_rank_lib import resolve_daily_volume_rank
|
from hub_volume_rank_lib import resolve_daily_volume_rank
|
||||||
from history_window_lib import (
|
from history_window_lib import (
|
||||||
PRESET_CUSTOM,
|
PRESET_CUSTOM,
|
||||||
@@ -6725,7 +6726,7 @@ def render_main_page(page="trade"):
|
|||||||
for o in raw_order_list:
|
for o in raw_order_list:
|
||||||
order_list.append(enrich_order_item(row_to_dict(o), current_capital))
|
order_list.append(enrich_order_item(row_to_dict(o), current_capital))
|
||||||
exchange_pnl_sync = {}
|
exchange_pnl_sync = {}
|
||||||
if exchange_private_api_configured():
|
if exchange_private_api_configured() and not request_is_hub_soft_nav():
|
||||||
try:
|
try:
|
||||||
exchange_pnl_sync = sync_trade_records_from_exchange(conn) or {}
|
exchange_pnl_sync = sync_trade_records_from_exchange(conn) or {}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<script src="/static/instance_theme.js?v=15"></script>
|
<script src="/static/instance_theme.js?v=16"></script>
|
||||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
||||||
<script src="/static/account_risk_badge.js?v=3"></script>
|
<script src="/static/account_risk_badge.js?v=3"></script>
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ from order_monitor_display_lib import (
|
|||||||
)
|
)
|
||||||
from wechat_notify_lib import build_wechat_rs_level_message, send_wechat_webhook
|
from wechat_notify_lib import build_wechat_rs_level_message, send_wechat_webhook
|
||||||
from hub_auth import request_allowed as hub_request_allowed
|
from hub_auth import request_allowed as hub_request_allowed
|
||||||
|
from instance_nav_lib import request_is_hub_soft_nav
|
||||||
from hub_volume_rank_lib import resolve_daily_volume_rank
|
from hub_volume_rank_lib import resolve_daily_volume_rank
|
||||||
from history_window_lib import (
|
from history_window_lib import (
|
||||||
PRESET_CUSTOM,
|
PRESET_CUSTOM,
|
||||||
@@ -6229,7 +6230,7 @@ def render_main_page(page="trade"):
|
|||||||
for o in raw_order_list:
|
for o in raw_order_list:
|
||||||
order_list.append(enrich_order_item(row_to_dict(o), current_capital))
|
order_list.append(enrich_order_item(row_to_dict(o), current_capital))
|
||||||
exchange_pnl_sync = {}
|
exchange_pnl_sync = {}
|
||||||
if exchange_private_api_configured():
|
if exchange_private_api_configured() and not request_is_hub_soft_nav():
|
||||||
try:
|
try:
|
||||||
exchange_pnl_sync = sync_trade_records_from_exchange(conn) or {}
|
exchange_pnl_sync = sync_trade_records_from_exchange(conn) or {}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<script src="/static/instance_theme.js?v=15"></script>
|
<script src="/static/instance_theme.js?v=16"></script>
|
||||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
<link rel="stylesheet" href="/static/account_risk_badge.css?v=3">
|
||||||
<script src="/static/account_risk_badge.js?v=3"></script>
|
<script src="/static/account_risk_badge.js?v=3"></script>
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
"""中控 iframe 内软导航:服务端跳过重型同步,避免切 tab 等待数秒。"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from flask import Request
|
||||||
|
|
||||||
|
|
||||||
|
def request_is_hub_soft_nav(req: Request | None = None) -> bool:
|
||||||
|
"""embed=1 且带 X-Instance-Soft-Nav 头:实例页内 fetch 换页,非整页刷新。"""
|
||||||
|
try:
|
||||||
|
from flask import request as flask_request
|
||||||
|
|
||||||
|
r = req or flask_request
|
||||||
|
if str(r.args.get("embed") or "").strip() != "1":
|
||||||
|
return False
|
||||||
|
flag = (r.headers.get("X-Instance-Soft-Nav") or "").strip().lower()
|
||||||
|
return flag in ("1", "true", "yes")
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
@@ -408,8 +408,6 @@
|
|||||||
if (!isHubLinked()) return;
|
if (!isHubLinked()) return;
|
||||||
|
|
||||||
let navToken = 0;
|
let navToken = 0;
|
||||||
const prefetch = new Map();
|
|
||||||
const PREFETCH_MAX = 8;
|
|
||||||
|
|
||||||
function isSoftNavLink(a) {
|
function isSoftNavLink(a) {
|
||||||
if (!a || !a.getAttribute) return false;
|
if (!a || !a.getAttribute) return false;
|
||||||
@@ -417,25 +415,11 @@
|
|||||||
return !!a.closest(".top-nav, .strategy-subnav");
|
return !!a.closest(".top-nav, .strategy-subnav");
|
||||||
}
|
}
|
||||||
|
|
||||||
function rememberPrefetch(href, html) {
|
function softNavFetch(href) {
|
||||||
if (!href || !html) return;
|
return fetch(href, {
|
||||||
if (prefetch.has(href)) prefetch.delete(href);
|
credentials: "same-origin",
|
||||||
prefetch.set(href, html);
|
headers: { "X-Instance-Soft-Nav": "1" },
|
||||||
while (prefetch.size > PREFETCH_MAX) {
|
});
|
||||||
const first = prefetch.keys().next().value;
|
|
||||||
prefetch.delete(first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function warmPrefetch(href) {
|
|
||||||
if (!href || prefetch.has(href)) return;
|
|
||||||
const token = navToken;
|
|
||||||
fetch(href, { credentials: "same-origin" })
|
|
||||||
.then((r) => (r.ok ? r.text() : null))
|
|
||||||
.then((html) => {
|
|
||||||
if (html && token === navToken) rememberPrefetch(href, html);
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function navigateInFrame(href, opts) {
|
async function navigateInFrame(href, opts) {
|
||||||
@@ -443,17 +427,13 @@
|
|||||||
notifyParentFrameNavStart();
|
notifyParentFrameNavStart();
|
||||||
ensureNavOverlay();
|
ensureNavOverlay();
|
||||||
try {
|
try {
|
||||||
let html = prefetch.get(href);
|
const r = await softNavFetch(href);
|
||||||
if (html) prefetch.delete(href);
|
|
||||||
if (!html) {
|
|
||||||
const r = await fetch(href, { credentials: "same-origin" });
|
|
||||||
if (token !== navToken) return;
|
if (token !== navToken) return;
|
||||||
if (!r.ok) {
|
if (!r.ok) {
|
||||||
location.assign(href);
|
location.assign(href);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
html = await r.text();
|
let html = await r.text();
|
||||||
}
|
|
||||||
if (token !== navToken) return;
|
if (token !== navToken) return;
|
||||||
html = injectNavOverlayIntoHtml(html, get());
|
html = injectNavOverlayIntoHtml(html, get());
|
||||||
let path = href;
|
let path = href;
|
||||||
@@ -494,22 +474,6 @@
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
document.addEventListener(
|
|
||||||
"pointerenter",
|
|
||||||
(ev) => {
|
|
||||||
const a = ev.target.closest("a[href]");
|
|
||||||
if (!a || !isSoftNavLink(a)) return;
|
|
||||||
const rawHref = a.getAttribute("href");
|
|
||||||
if (!rawHref || rawHref.startsWith("#") || rawHref.startsWith("javascript:")) return;
|
|
||||||
try {
|
|
||||||
const target = new URL(rawHref, location.href);
|
|
||||||
if (target.origin !== location.origin) return;
|
|
||||||
warmPrefetch(target.pathname + target.search + target.hash);
|
|
||||||
} catch (_) {}
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
window.addEventListener("popstate", () => {
|
window.addEventListener("popstate", () => {
|
||||||
void navigateInFrame(location.pathname + location.search + location.hash, { replace: true });
|
void navigateInFrame(location.pathname + location.search + location.hash, { replace: true });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from instance_nav_lib import request_is_hub_soft_nav
|
||||||
|
|
||||||
|
|
||||||
|
def test_request_is_hub_soft_nav():
|
||||||
|
class Req:
|
||||||
|
args = {"embed": "1"}
|
||||||
|
headers = {"X-Instance-Soft-Nav": "1"}
|
||||||
|
|
||||||
|
assert request_is_hub_soft_nav(Req()) is True
|
||||||
|
|
||||||
|
class Req2:
|
||||||
|
args = {"embed": "1"}
|
||||||
|
headers = {}
|
||||||
|
|
||||||
|
assert request_is_hub_soft_nav(Req2()) is False
|
||||||
|
|
||||||
|
class Req3:
|
||||||
|
args = {}
|
||||||
|
headers = {"X-Instance-Soft-Nav": "1"}
|
||||||
|
|
||||||
|
assert request_is_hub_soft_nav(Req3()) is False
|
||||||
Reference in New Issue
Block a user