普通のノート PC でも速い理由。
取引画面は重いものです。長い履歴、止まらないティック、1 ページに並ぶ多くのチャート。TradeCanvas は各フレームに必要な仕事だけを、メインスレッドで、サードパーティのコードなしで行います。このページではその方法と、まだ改善中の点を示します。
開発中: エンジンは実用に十分な速さですが、到達すべき速さにはまだ届いていません。最後のセクションに残りの課題を挙げています。
小さなパッケージ、一方向の依存
各パッケージは下にあるパッケージにだけ依存します。TradeCanvas 以外のコードはページで動きません。フレームワーク用コンポーネントは React・Vue・Svelte を peer として受け取り、WebGL レンダラーはチャートが求めたときだけ読み込む別チャンクです。
0 実行時のサードパーティ依存
ティックがたどる道
フィードからの価格は 1 フレームで画面に届きます。各段階は変わった部分だけを処理します。
- 1あなたのフィード
DataAdapterWebSocket、REST、証券会社: 履歴とストリームがあれば何でも。 - 2ストリーム管理
StreamManager先に履歴、次にライブ。古いリクエストの応答は捨て、黙ったフィードは 30 秒以内に気づきます。 - 3ティック集約
TickAggregatorティックは 1,000 件のリングバッファーに入り、その時間足の足にまとめられます。 - 4指標
IndicatorEngine系列の最初からではなく、最後の足から再計算します。 - 5ビューポート
Viewport画面に見える足だけを走査し、価格軸もそれだけから決めます。 - 6描画ループ
RenderLoopティックがいくつ来ても、シーンの描画はアニメーションフレームごとに最大 1 回です。 - 7Canvas 2D または WebGL
RenderEngineキャンバス 2 枚、WebGL をオンにするとその下に GPU キャンバス。
ティック 1 つは足 1 本分のコスト、履歴全体ではありません
ティックが最後の足を変えると、各指標は系列全体を再計算せず、その足(と式が振り返る数本)から続きを計算します。覚えている足が一致しなくなれば全体の再計算に戻るので、データの訂正を見逃しません。
約 20 の指標が独自の増分更新を持ち、さらに 31 の指標が点ごとに続きを計算する基盤の上に作られています。他の指標の線を読む指標も続きから計算します。
縮小したら、ピクセルごとに 1 列
足が 1 ピクセルより細くなると、1 本ずつ描くのは目に見えない無駄です。ローソク足、バー、高安、出来高はピクセルごとに 1 列で描き、その下の足の最初の始値、最高値、最安値、最後の終値を使います。線とエリアはピクセルあたり約 2 点 (LTTB)、指標の線と帯はピクセル列ごとに 1 区間を描きます。
- 表示中の足
- 313
- ピクセルあたりの足
- 0.39
- 描いた図形
- 313
足は CSS ピクセルの 4 分の 1 より細くなりません。そのため 100 万本を持つチャートでも最大まで縮小すると表示はピクセルあたり約 4 本、1,600 px のチャートで約 6,400 本です。100 万本ベンチマークは残りをパンする性能を測ります。
キャンバス 2 枚、だからホバーはほぼ無料
シーン(グリッド、系列、指標、描画、注文)は 1 枚のキャンバスに、クロスヘア、凡例、軸ラベル、カウントダウンはその上の薄いキャンバスにあります。マウスを動かすと上のキャンバスだけを描き直します。データの更新は次のフレームでシーンを 1 回描きます。
全画面サイズのキャンバスごとに、ブラウザーはフレームごとに合成を 1 回増やします。そのためエンジンはキャンバスを少なく保ち、2D 専用の描画用の裏キャンバスは必要なときだけ置きます。
書き直さず、記録して WebGL へ
チャートは Canvas 2D の呼び出しで描きます。WebGL がオンなら、その呼び出しはレコーダーに渡り、パス、塗り、線がデバイスピクセル単位の GPU コマンドになります。GPU が同じように描けないものは順序を保ったまま Canvas 2D に残るので、どちらでも絵は同じです。
- パス、塗り、線
- ローソク足、出来高、グリッドをインスタンス描画
- 系列は 1 つの Float32Array に足 1 本 6 値、ティックは末尾だけを書き換え
- テキスト
- 画像とパターン
- 影、フィルター、特殊なクリップ
- GPU が受け取れない最初のステップ以降のすべて
renderer: 'auto'は大きな性能上の注意がないコンテキストを求めるので、WebGL がソフトウェアで動く環境では Canvas 2D のままです。- 1 ページで WebGL コンテキストを持てるチャートは最大 8 つです (
setMaxWebGLCharts)。残りは待ち行列に入り Canvas 2D で描きます。 - GPU がコンテキストを失っても、チャートは Canvas 2D で描き続け、コンテキストが戻れば WebGL で組み直します。
- ローソク足はシェーダーと CPU で同じ規則によりデバイスピクセルに揃えられ、両方のレンダラーが同じピクセルに描きます。
非力な環境のために
- 既定は Canvas 2DWebGL はより多くの環境で測定されるまでオプトインです。高いピクセル比の内蔵グラフィックスでは、描画ではなくブラウザーの合成がボトルネックです。
- リサイズはフレームに 1 回リサイズイベントはフレームごとに 1 回にまとめられ、サイズが変わらなければ何もしません。
- 履歴はページ単位過去へスクロールすると古い足を 500 本ずつ、一度に 1 リクエスト、失敗後は間隔を空けながら読み込みます。
- 読み込みのちらつきなし読み込み表示は 200 ms 待つので、素早い銘柄切り替えでちらつきません。
- 小さなダウンロードヘッドレスチャートは gzip 後 176 KB、ウィジェット全体で 315 KB、WebGL レンダラーは使うときに 18 KB 追加です。
- その場で更新される株価ボードbo-grid の株価ボードはティックをフレームごとに 1 回のパッチにまとめ、変わったセルだけを描き直します。