Saya memiliki setInterval
menjalankan sepotong kode 30 kali per detik. Ini berfungsi dengan baik, namun ketika saya memilih tab lain (sehingga tab dengan kode saya menjadi tidak aktif), setInterval
ini diatur ke keadaan siaga karena beberapa alasan.
Saya membuat test case yang disederhanakan ini ( http://jsfiddle.net/7f6DX/3/ ):
var $div = $('div');
var a = 0;
setInterval(function() {
a++;
$div.css("left", a)
}, 1000 / 30);
Jika Anda menjalankan kode ini dan kemudian beralih ke tab lain, tunggu beberapa detik dan kembali, animasi berlanjut pada titik ketika Anda beralih ke tab lain. Jadi animasi tidak berjalan 30 kali per detik jika tab tidak aktif. Ini dapat dikonfirmasi dengan menghitung berapa kali setInterval
fungsi dipanggil setiap detik - ini tidak akan menjadi 30 tetapi hanya 1 atau 2 jika tab tidak aktif.
Saya kira ini dilakukan oleh desain untuk meningkatkan kinerja, tetapi apakah ada cara untuk menonaktifkan perilaku ini? Ini sebenarnya merupakan kerugian dalam skenario saya.
sumber
Date
objek untuk benar-benar melihat waktu telah berlalu.Date
. Sehingga ketika interval tidak menyala dengan cepat (untuk alasan ini atau lainnya) animasi menjadi semakin menyebalkan, tidak lebih lambat.Jawaban:
Pada sebagian besar browser, tab yang tidak aktif memiliki eksekusi prioritas rendah dan ini dapat memengaruhi pengatur waktu JavaScript.
Jika nilai transisi Anda dihitung menggunakan waktu nyata yang berlalu di antara bingkai alih-alih memperbaiki kenaikan pada setiap interval, Anda tidak hanya menyelesaikan masalah ini tetapi juga dapat mencapai animasi yang lebih baik dengan menggunakan requestAnimationFrame karena dapat mencapai 60fps jika prosesor tidak mencapai sangat sibuk.
Berikut ini adalah contoh JavaScript vanilla dari transisi properti animasi menggunakan
requestAnimationFrame
:Untuk Tugas Latar Belakang (terkait non-UI)
@UpTheCreek komentar:
Jika Anda memiliki tugas latar belakang yang perlu dieksekusi secara tepat pada interval yang diberikan, Anda dapat menggunakan Pekerja Web HTML5 . Lihatlah jawaban Möhre di bawah ini untuk lebih jelasnya ...
CSS vs JS "animasi"
Masalah ini dan banyak lainnya dapat dihindari dengan menggunakan transisi / animasi CSS alih-alih animasi berbasis JavaScript yang menambahkan overhead yang cukup besar. Saya akan merekomendasikan plugin jQuery ini yang memungkinkan Anda mengambil manfaat dari transisi CSS seperti
animate()
metode.sumber
before = now;
untuk mendapatkan waktu yang telah berlalu sejak awal, bukan akhir dari panggilan sebelumnya. Ini biasanya yang Anda inginkan saat menjiwai sesuatu. Seperti sekarang, jika eksekusi fungsi interval membutuhkan waktu 15 ms,elapsedTime
akan memberikan 35 ms (bukan 50 ms yang merupakan interval) lain kali dipanggil (saat tab aktif).Saya mengalami masalah yang sama dengan audio fading dan pemutar HTML5. Itu terhenti ketika tab menjadi tidak aktif. Jadi saya menemukan WebWorker diizinkan menggunakan interval / batas waktu tanpa batasan. Saya menggunakannya untuk mengirim "kutu" ke javascript utama.
Kode WebWorkers:
Javascript Utama:
sumber
Ada solusi untuk menggunakan Pekerja Web (seperti yang disebutkan sebelumnya), karena mereka berjalan dalam proses terpisah dan tidak melambat
Saya telah menulis skrip kecil yang dapat digunakan tanpa perubahan pada kode Anda - ini hanya mengabaikan fungsi setTimeout, clearTimeout, setInterval, clearInterval.
Cukup sertakan sebelum semua kode Anda.
info lebih lanjut di sini
sumber
Lakukan saja ini:
Tab browser yang tidak aktif menyangga sebagian
setInterval
atausetTimeout
fungsinya.stop(true,true)
akan menghentikan semua acara yang disangga dan menjalankan hanya animasi terakhir dengan segera.The
window.setTimeout()
Metode sekarang klem untuk mengirim tidak lebih dari satu batas waktu per detik di tab yang tidak aktif. Selain itu, sekarang klem timeout bersarang ke nilai terkecil yang diizinkan oleh spesifikasi HTML5: 4 ms (bukan 10 ms yang digunakan untuk clamp).sumber
Saya pikir pemahaman terbaik tentang masalah ini adalah dalam contoh ini: http://jsfiddle.net/TAHDb/
Saya melakukan hal sederhana di sini:
Memiliki interval 1 detik dan setiap kali menyembunyikan rentang pertama dan memindahkannya ke yang terakhir, dan menunjukkan rentang ke-2.
Jika Anda tetap pada halaman itu berfungsi seperti yang seharusnya. Tetapi jika Anda menyembunyikan tab selama beberapa detik, ketika Anda kembali Anda akan melihat hal yang aneh.
Ini seperti semua acara yang tidak ucur selama waktu Anda tidak aktif sekarang akan terjadi semua dalam 1 waktu. jadi selama beberapa detik Anda akan mendapatkan seperti acara X. mereka begitu cepat sehingga memungkinkan untuk melihat semua 6 bentang sekaligus.
Jadi jahitan chrome hanya menunda acara, jadi ketika Anda kembali semua acara akan terjadi tetapi sekaligus ...
Sebuah aplikasi praktis adalah aplikasi ini untuk tampilan slide sederhana. Bayangkan angkanya menjadi Gambar, dan jika pengguna tetap dengan tab disembunyikan ketika kembali, ia akan melihat semua gambar mengambang, Benar-benar memuakkan.
Untuk memperbaikinya gunakan stop (true, true) seperti yang dikatakan pimvdb. Ini akan menghapus antrian acara.
sumber
requestAnimationFrame
jQuery yang digunakan. Karena beberapa keanehan yang dimilikinya (seperti ini), mereka menghapusnya. Di 1,7 Anda tidak melihat perilaku ini. jsfiddle.net/TAHDb/1 . Karena intervalnya sekali per detik ini sebenarnya tidak mempengaruhi masalah yang saya posting, karena maksimum untuk tab tidak aktif juga sekali per detik - sehingga tidak ada bedanya.Bagi saya itu tidak penting untuk memutar audio di latar belakang seperti untuk orang lain di sini, masalah saya adalah bahwa saya memiliki beberapa animasi dan mereka bertindak seperti orang gila ketika Anda berada di tab lain dan kembali kepada mereka. Solusi saya adalah meletakkan animasi ini di dalam jika itu mencegah tab tidak aktif :
berkat itu animasi saya hanya berjalan jika tab aktif. Saya harap ini akan membantu seseorang dengan kasus saya.
sumber
setInterval(() => !document.hidden && myfunc(), 1000)
dan berfungsi dengan baikKeduanya
setInterval
danrequestAnimationFrame
tidak berfungsi saat tab tidak aktif atau berfungsi tetapi tidak pada periode yang tepat. Solusinya adalah menggunakan sumber lain untuk peristiwa waktu. Misalnya soket web atau pekerja web adalah dua sumber acara yang berfungsi dengan baik saat tab tidak aktif. Jadi tidak perlu memindahkan semua kode Anda ke pekerja web, cukup gunakan pekerja sebagai sumber peristiwa waktu:.
Link jsfiddle dari sampel ini.
sumber
Sangat dipengaruhi oleh perpustakaan Ruslan Tushov, saya telah membuat perpustakaan kecil saya sendiri . Cukup tambahkan skrip di dalam
<head>
dan itu akan menambalsetInterval
dansetTimeout
dengan yang digunakanWebWorker
.sumber
Memutar file audio memastikan kinerja Javascript latar belakang penuh untuk saat ini
Bagi saya, itu adalah solusi paling sederhana dan paling tidak mengganggu - selain memainkan suara yang samar / hampir kosong, tidak ada efek samping potensial lainnya
Anda dapat menemukan detailnya di sini: https://stackoverflow.com/a/51191818/914546
(Dari jawaban lain, saya melihat bahwa beberapa orang menggunakan properti berbeda dari tag Audio, saya bertanya-tanya apakah mungkin menggunakan tag Audio untuk kinerja penuh, tanpa benar-benar memainkan sesuatu)
sumber
catatan: solusi ini tidak cocok jika interval Anda suka bekerja di latar belakang, misalnya, memutar audio atau ... tetapi jika Anda bingung misalnya tentang animasi Anda tidak berfungsi dengan benar ketika kembali ke halaman Anda (tab) ini adalah solusi yang bagus.
Ada banyak cara untuk mencapai tujuan ini, mungkin "WebWorkers" adalah yang paling standar tetapi tentu saja, itu bukan yang termudah dan praktis, terutama Jika Anda tidak punya cukup waktu, maka Anda dapat mencoba cara ini:
► KONSEP BASIS:
1- membuat nama untuk interval Anda (atau animasi) dan mengatur interval Anda (animasi), sehingga akan berjalan ketika pengguna pertama kali membuka halaman Anda:
var interval_id = setInterval(your_func, 3000);
2- oleh
$(window).focus(function() {});
dan$(window).blur(function() {});
Anda dapatclearInterval(interval_id)
setiap browser (tab) dinonaktifkan dan Jalankan kembali interval Anda (animasi) setiap browser (tab) akan aktif kembali denganinterval_id = setInterval();
►CODE KODE:
sumber
Ini pertanyaan yang cukup lama tapi saya mengalami masalah yang sama.
Jika Anda menjalankan web di chrome, Anda dapat membaca posting ini Background Tabs di Chrome 57 .
Pada dasarnya timer interval bisa berjalan jika belum habis dari anggaran timer.
Konsumsi anggaran didasarkan pada penggunaan waktu CPU dari tugas di dalam timer.
Berdasarkan skenario saya, saya menggambar video ke kanvas dan transportasi ke WebRTC.
Koneksi video webrtc akan terus memperbarui bahkan tab tidak aktif.
Namun Anda harus menggunakan
setInterval
bukanrequestAnimationFrame
.tidak direkomendasikan untuk rendering UI.
Akan lebih baik untuk mendengarkan
visibilityChange
acara dan mengubah membuat mekanisme.Selain itu, Anda dapat mencoba @ kaan-soral dan itu harus berfungsi berdasarkan dokumentasi.
sumber
Inilah solusi kasar saya
sumber
postMessageHandler
memanggil acara sendiri itu adalah penanganan, sehingga memiliki loop tak terbatas yang tidak menghalangi UI. Dan sementara itu berulang tanpa henti itu memeriksa dengan setiap penanganan acara jika ada fungsi timeout atau interval untuk dijalankan.Saya dapat memanggil fungsi panggilan balik saya minimal 250ms menggunakan tag audio dan menangani acara pembaruan waktu. Disebut 3-4 kali dalam satu detik. Lebih baik dari setTimeout lagging kedua
sumber