Bagaimana ia tetap cepat di laptop biasa.
Layar trading itu berat: riwayat panjang, tick yang tak pernah berhenti, banyak grafik dalam satu halaman. TradeCanvas bekerja sesedikit yang dibutuhkan setiap frame, di main thread, tanpa kode pihak ketiga. Halaman ini menunjukkan caranya, dan di mana ia masih diperbaiki.
Masih dalam pengerjaan: mesinnya cukup cepat untuk dirilis, tetapi belum secepat nantinya. Bagian terakhir mencantumkan apa yang kami tahu masih tersisa.
Paket kecil, satu arah
Setiap paket hanya bergantung pada paket di bawahnya. Tidak ada kode dari luar TradeCanvas yang berjalan di halaman Anda: komponen framework menjadikan React, Vue, atau Svelte sebagai peer, dan perender WebGL adalah chunk terpisah yang hanya dimuat saat sebuah grafik memintanya.
0 dependensi runtime pihak ketiga
Perjalanan sebuah tick
Harga datang dari feed Anda dan sampai ke layar dalam satu frame. Setiap tahap hanya mengerjakan bagian yang berubah.
- 1Feed Anda
DataAdapterWebSocket, REST, broker: apa pun yang punya riwayat dan stream. - 2Pengelola stream
StreamManagerRiwayat dulu, lalu langsung. Jawaban dari permintaan lama dibuang; feed yang diam terdeteksi dalam 30 detik. - 3Agregator tick
TickAggregatorTick masuk ke ring buffer berisi 1.000 dan dilipat ke bar kerangka waktunya. - 4Indikator
IndicatorEngineDihitung ulang dari bar terakhir, bukan dari awal seri. - 5Viewport
ViewportHanya bar di layar yang ditelusuri; skala harga berasal dari bar itu saja. - 6Loop render
RenderLoopBerapa pun tick yang datang, adegan digambar paling banyak sekali per frame animasi. - 7Canvas 2D atau WebGL
RenderEngineDua kanvas, dan kanvas GPU di bawahnya saat WebGL aktif.
Satu tick seharga satu bar, bukan seluruh riwayat
Saat tick mengubah bar terakhir, setiap indikator melanjutkan dari bar itu (dan beberapa bar sebelumnya yang dilihat rumusnya) alih-alih menghitung ulang seluruh seri. Jika bar yang diingatnya tidak lagi cocok, indikator kembali ke perhitungan ulang penuh, sehingga koreksi tidak pernah terlewat.
Sekitar 20 indikator punya pembaruan inkremental sendiri, dan 31 lainnya dibangun di atas basis yang melanjutkan titik demi titik. Indikator yang membaca garis indikator lain juga melanjutkan.
Saat diperkecil: satu kolom per piksel
Saat bar lebih sempit dari satu piksel, menggambar masing-masing hanya membuang kerja yang tak terlihat mata. Candle, bar, high-low, dan volume digambar sebagai satu kolom per piksel, dengan open pertama, high tertinggi, low terendah, dan close terakhir dari bar di bawahnya. Garis dan area menyimpan sekitar dua titik per piksel (LTTB); garis dan band indikator menggambar satu rentang per kolom piksel.
- bar terlihat
- 313
- bar per piksel
- 0,39
- bentuk digambar
- 313
Bar tidak pernah lebih sempit dari seperempat piksel CSS, jadi grafik berisi sejuta bar menampilkan paling banyak sekitar empat bar per piksel saat diperkecil sepenuhnya: sekitar 6.400 pada grafik 1.600 px. Menggeser melewati sisanya adalah yang diukur benchmark sejuta bar.
Dua kanvas, jadi hover nyaris tanpa biaya
Adegan (grid, seri, indikator, gambar, order) ada di satu kanvas; crosshair, legenda, label sumbu, dan hitung mundur ada di kanvas tipis di atasnya. Menggerakkan mouse hanya menggambar ulang kanvas atas. Pembaruan data menggambar ulang adegan sekali, di frame berikutnya.
Setiap kanvas berukuran penuh membebani browser dengan satu blend per frame, jadi mesin menjaga jumlahnya sedikit: kanvas belakang untuk gambar khusus 2D hanya ada selama ada yang membutuhkannya.
WebGL dengan merekam, bukan menulis ulang
Grafik menggambar dengan panggilan Canvas 2D. Saat WebGL aktif, panggilan itu masuk ke perekam yang mengubah path, isian, dan stroke menjadi perintah GPU dalam piksel perangkat. Apa pun yang tidak bisa digambar GPU dengan sama tetap di Canvas 2D, sesuai urutan, sehingga gambarnya sama dengan cara mana pun.
- path, isian, dan stroke
- candle, volume, dan grid sebagai instanced draw
- seri dalam satu Float32Array, enam float per bar; tick hanya menulis ulang bagian ekornya
- teks
- gambar dan pola
- bayangan, filter, clip yang tak lazim
- apa pun setelah langkah pertama yang tidak bisa diambil GPU
renderer: 'auto'meminta browser sebuah konteks tanpa peringatan performa besar, jadi mesin yang WebGL-nya akan berjalan di perangkat lunak tetap memakai Canvas 2D.- Paling banyak 8 grafik dalam satu halaman memegang konteks WebGL (
setMaxWebGLCharts); sisanya menunggu dalam antrean dan menggambar dengan Canvas 2D. - Jika GPU melepas konteksnya, grafik tetap berjalan dengan Canvas 2D dan dibangun ulang di WebGL saat konteksnya kembali.
- Candle dibulatkan ke piksel perangkat utuh dengan aturan yang sama di shader dan di CPU, jadi kedua perender menempatkannya pada piksel yang sama.
Dibuat untuk mesin yang lemah
- Canvas 2D secara bawaanWebGL bersifat opsional sampai diukur di lebih banyak perangkat. Pada grafis terintegrasi dengan rasio piksel tinggi, yang menjadi hambatan adalah compositing browser sendiri, bukan penggambarannya.
- Satu resize per frameEvent resize digabung menjadi satu per frame, dan ukuran yang tidak berubah tidak melakukan apa-apa.
- Riwayat per halamanBar lama dimuat 500 sekaligus saat Anda menggulir mundur, satu permintaan pada satu waktu, dan menunda percobaan setelah gagal.
- Tanpa kedipan loadingSelubung loading menunggu 200 ms, jadi pergantian simbol yang cepat tidak pernah berkedip.
- Kecil untuk diunduhGrafik headless berukuran 176 KB setelah gzip, widget lengkap 315 KB, dan perender WebGL 18 KB lagi saat dipakai.
- Papan yang diperbarui di tempatPapan harga bo-grid menggabungkan tick menjadi satu tambalan per frame dan hanya menggambar ulang sel yang berubah.