Aplikasi gambar berbasis stilus yang dibuat untuk web telah lama mengalami masalah latensi karena halaman web harus menyinkronkan update grafis dengan DOM. Dalam aplikasi gambar apa pun, latensi yang lebih dari 50 milidetik dapat mengganggu koordinasi tangan-mata pengguna, sehingga aplikasi sulit digunakan.
Petunjuk desynchronized
untuk canvas.getContext()
memanggil jalur kode
yang berbeda yang mengabaikan mekanisme pembaruan DOM biasa.
Sebagai gantinya, petunjuk tersebut memberi tahu sistem yang mendasarinya untuk melewati sebanyak mungkin
komposisi dan dalam beberapa kasus, buffer dasar kanvas dikirim langsung ke
pengontrol tampilan layar. Hal ini menghilangkan latensi yang akan
ditimbulkan oleh penggunaan antrean perender compositor.
Seberapa bagus produk ini?
Jika Anda ingin melihat kodenya, scroll ke depan. Untuk melihatnya beraksi, Anda memerlukan perangkat dengan layar sentuh, dan sebaiknya stilus. (Jari juga berfungsi.) Jika Anda memilikinya, coba contoh 2d atau webgl. Untuk Anda yang lain, lihat demo oleh Miguel Casas ini, salah satu engineer yang menerapkan fitur ini. Buka demo, tekan putar, lalu gerakkan penggeser bolak-balik secara acak dan cepat.
Contoh ini menggunakan klip berdurasi satu menit dua puluh satu detik dari film pendek
Sintel oleh Durian, project film terbuka
Blender. Dalam contoh ini, film diputar di elemen <video>
yang
kontennya dirender secara bersamaan ke elemen <canvas>
. Banyak perangkat dapat
melakukannya tanpa tearing, meskipun perangkat dengan rendering buffering depan seperti
ChromeOS misalnya mungkin mengalami tearing. (Filmnya bagus, tetapi menyedihkan.
Saya tidak berguna selama satu jam setelah melihatnya. Harap perhatikan.)
Menggunakan petunjuk
Ada lebih banyak hal yang dapat dilakukan untuk menggunakan latensi rendah selain menambahkan desynchronized
ke
canvas.getContext()
. Saya akan membahas masalah satu per satu.
Membuat kanvas
Pada API lain, saya akan membahas deteksi fitur terlebih dahulu. Untuk petunjuk desynchronized
,
Anda harus membuat kanvas terlebih dahulu. Panggil canvas.getContext()
dan teruskan
petunjuk desynchronized
baru dengan nilai true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('2d', {
desynchronized: true,
// Other options. See below.
});
Deteksi fitur
Selanjutnya, panggil getContextAttributes()
. Jika objek atribut yang ditampilkan memiliki
properti desynchronized
, uji objek tersebut.
if (ctx.getContextAttributes().desynchronized) {
console.log('Low latency canvas supported. Yay!');
} else {
console.log('Low latency canvas not supported. Boo!');
}
Menghindari kedipan
Ada dua kasus yang dapat menyebabkan kedipan jika Anda tidak membuat kode dengan benar.
Beberapa browser, termasuk Chrome, menghapus kanvas WebGL di antara frame. Pengontrol
layar dapat membaca buffer saat kosong sehingga
gambar yang digambar akan berkedip. Untuk menghindari hal ini, tetapkan
preserveDrawingBuffer
ke true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
desynchronized: true,
preserveDrawingBuffer: true
});
Flicker juga dapat terjadi saat Anda menghapus konteks layar dalam kode gambar Anda sendiri. Jika Anda harus menghapus, gambar ke framebuffer di luar layar, lalu salin ke layar.
Saluran alfa
Elemen kanvas transparan, yang alpha-nya disetel ke true, masih dapat didesinkronkan, tetapi tidak boleh memiliki elemen DOM lain di atasnya.
Hanya boleh ada satu
Anda tidak dapat mengubah atribut konteks setelah panggilan pertama ke
canvas.getContext()
. Hal ini selalu benar, tetapi mengulanginya mungkin dapat menghemat
ketidaknyamanan jika Anda tidak mengetahui atau lupa .
Misalnya, misalkan saya mendapatkan konteks dan menentukan alpha sebagai salah, lalu
di lain waktu dalam kode saya, saya memanggil canvas.getContext()
untuk kedua kalinya dengan alpha
ditetapkan ke benar seperti yang ditunjukkan di bawah.
const canvas = document.querySelector('myCanvas');
const ctx1 = canvas.getContext('2d', {
alpha: false,
desynchronized: true,
});
//Some time later, in another corner of code.
const ctx2 = canvas.getContext('2d', {
alpha: true,
desynchronized: true,
});
Tidak jelas bahwa ctx1
dan ctx2
adalah objek yang sama. Alfa masih salah dan
konteks dengan alfa sama dengan benar tidak pernah dibuat.
Jenis kanvas yang didukung
Parameter pertama yang diteruskan ke getContext()
adalah contextType
. Jika sudah
terbiasa dengan getContext()
, Anda pasti bertanya-tanya apakah ada
hal lain selain jenis konteks '2d' yang didukung. Tabel di bawah menunjukkan jenis
konteks yang mendukung desynchronized
.
contextType | Objek jenis konteks |
---|---|
|
|
|
|
|
|
Kesimpulan
Jika Anda ingin melihat lebih banyak hal ini, lihat contohnya. Selain contoh video yang telah dijelaskan, ada contoh yang menampilkan konteks '2d' dan 'webgl'.