從快照到時間序列:一次實時行情繫統的結構演進與架構取捨
在多數前端行情繫統中,Ticker 快照接口足以支撐列表展示:最新價、漲跌幅、成交量定時刷新即可。
但當系統開始引入 K 線圖表後,前端架構會發生一次實質性的結構變化。
這篇文章不討論某個具體 API 如何調用,而是圍繞一次真實的結構升級過程,覆盤一個典型行情繫統從“點數據展示”到“時間序列建模”的演進路徑。
本文重點包括:
- Ticker 快照模型的邊界
- 主從結構下的狀態管理重構
- 時間序列緩存與歷史預加載設計
- 實時 K 線的增量更新策略
- REST 與 WebSocket 的架構取捨
- 行情繫統的階段性演進總結
一、問題背景:Ticker 模型的天然邊界
在初始版本中,系統僅包含行情列表:
此時系統的核心模型是 Ticker 快照:
- 每次請求返回當前狀態
- 無時間維度
- 定時刷新即可完成數據更新
這種模型的優點是:
- 實現簡單
- 狀態單一
- 易於維護
但它存在明顯邊界:
- 無法展示歷史趨勢
- 無法支持滾動查看
- 無法表達“結構”變化
當需求從“當前價格”轉向“價格如何變化”,系統必須引入時間維度。
這一步,才是真正的結構轉折。
二、從單表結構到主從架構
引入 K 線圖表後,界面從單列表演進為主從結構:
行情列表(主) → 選中 symbol → 詳情面板(從)
詳情面板包含:
- 當前行情快照
- K 線時間序列圖表
此時問題不再是 UI,而是狀態管理。
原來只需要維護:
- symbol 列表
- 定時刷新狀態
現在必須維護:
- 當前選中 symbol
- 當前時間週期 interval
- 是否緩存 symbol@interval 數據
- 當前圖表可視範圍
數據粒度從:
symbol
升級為:
symbol@interval
這是第一次真正的數據模型升級。
三、時間序列緩存與歷史預加載
時間序列數據如果每次都重新請求,會產生明顯延遲。
因此需要:
- 首次加載固定數量(如 50 根)
- 可視區域佔 2/3
- 預留 1/3 作為緩衝區
- 左滑時觸發歷史數據預加載
邏輯示意:
if (visibleRange.left < threshold) {
loadMoreHistory(symbol, interval)
}
關鍵點:
- 防抖控制
- 避免重複請求
- 數據合併時保持時間順序
- 不改變當前可視範圍
此時模型已經從“請求驅動渲染”轉為“滾動驅動加載”。
四、實時 K 線更新:增量而非重建
歷史數據是靜態結構,而當前週期是動態結構。
更新邏輯應當是增量的:
if (latest.timestamp === lastBar.timestamp) {
updateLastBar(latest)
} else {
appendNewBar(latest)
}
核心思想:
- 只更新最後一根
- 不重建整個數組
- 保持滾動位置穩定
否則圖表會出現跳動。
五、圖表渲染中的性能問題
引入圖表後,常見兩個問題:
1. resize 抖動
解決方式:
- 監聽容器尺寸變化
- 延遲觸發 resize
- 保持 visibleRange 不變
2. 圖表跳動
通常因為:
- 使用 setData 重建數據
- 未保存滾動位置
解決策略:
- 使用 update 增量更新
- 保留可視範圍
六、REST 與 WebSocket 的設計取捨
當系統引入時間序列後,常見問題是:是否需要 WebSocket?
REST 的優勢
- 實現簡單
- 易於調試
- 請求頻率可控
- 架構複雜度低
WebSocket 的優勢
- 延遲更低
- 適合 Tick 級別數據
- 支持高頻推送
但在分鐘級 K 線場景中:
- 不需要 Tick 級精度
- 週期級刷新即可滿足需求
- WebSocket 會增加連接與狀態管理複雜度
因此,在當前階段選擇 REST + 定時刷新,是複雜度與收益之間的平衡。
架構選擇的核心不是“先進”,而是“匹配場景”。
七、行情繫統的演進路徑
一次 K 線接入,背後是系統的階段性演進:
第一階段:快照展示階段
- 定時刷新
- 無歷史結構
- 列表為核心
第二階段:時間序列階段
- 引入 K 線
- 引入緩存模型
- 引入預加載機制
- 主從結構形成
第三階段(可擴展)
- WebSocket 增量推送
- 本地聚合計算
- 多市場統一流管理
此時系統從“展示工具”演進為“數據結構系統”。
八、完整演示效果
結語
從 Ticker 快照到時間序列建模,是實時行情繫統的一次範式轉移。
它改變的不只是界面,而是:
- 數據抽象方式
- 狀態管理模型
- 請求策略
- 渲染策略
理解這條演進路徑,比掌握某個圖表庫 API 更重要。
當系統開始處理“時間結構”,架構複雜度自然提升。
這也是每一個行情繫統都會經歷的階段。
參考資料
本文示例的完整結構代碼整理於公開倉庫,主要用於輔助理解時間序列建模與前端架構設計思路:https://github.com/TickDB/tickdb-demo-ticker-panel