← 回首頁

為什麼你的時間序列圖表畫到十萬點就卡住

瓶頸幾乎不在圖表套件,而在你丟給瀏覽器的繪製次數。有三個方向可以砍。

一台筆電螢幕上是一張密到線條糊在一起的時間序列圖,周圍漂浮著各種圖表卡片。

接上一週的 tick 資料,圖表一畫,整個頁面就卡死。第一直覺通常是怪圖表套件,然後開始 找「更快的那一個」。這多半是錯的方向——主流套件之間的效能差距大多在兩倍以內,而換套件 會花掉你一整天。

真正的瓶頸

瀏覽器不在乎你有一百萬筆資料,它在乎的是要畫幾個東西。以 SVG 為底的圖表,每一個 資料點就是一個 DOM 節點;一百萬點就是一百萬個節點,版面計算、樣式重算、繪製全部跟著 這個數字放大。換一個更快的套件,救不了這件事。

砍繪製次數的三個方向

一般人會踩到的地方

最天真的降採樣——每 n 筆取一筆——會剛好抹掉你當初做這張圖是為了看到的那根尖刺。每一百 筆取一筆的價格序列,會安靜地把那根關鍵的 K 棒丟掉。

選著「每 n 筆取一筆」把點數往下拖,看那根尖刺消失。然後不要動滑桿,只切換演算法 ——點數一模一樣,尖刺回來了。

降採樣試玩
演算法

保留 100 / 2000 點尖刺被丟掉了

Largest-Triangle-Three-Buckets 這類演算法就是為此存在的:它保留的是能維持序列視覺 形狀的那些點,而不是剛好落在固定間隔上的點。輸出的點數跟天真取樣一樣,但看起來跟原圖 接近得多。

常見追問

降採樣會不會把真正的極值弄不見?

挑錯演算法才會。「每 n 筆取一筆」會丟掉取樣點之間的所有東西,只有一個 tick 的尖刺就這樣消失了。Largest-Triangle-Three-Buckets 保留的是決定這條線形狀的 那些點,極值包含在內。

瀏覽器實際上畫得動幾個點?

用 SVG,大約超過一萬點就開始出問題——每個點都是一個要排版、要套樣式的 DOM 節點。用 canvas 只有一個元素、一次繪製,幾萬點是很平常的量。

降採樣要在後端做還是瀏覽器做?

讀者不會放大看原始序列的話,在後端做,順便省下大量傳輸。可以放大的話就在 瀏覽器做——每一個縮放層級需要的是從原始資料重新取的一組樣本。