Chrome: arka plan sekmelerinde askıya alınan zaman aşımı / aralık?


130

Bu testisetTimeout kullanmanın doğruluğunu test ediyordum . Şimdi fark ettim (beklendiği gibi) çok doğru değil, ancak çoğu cihaz için önemli ölçüde yanlış değil. Şimdi testi Chrome'da çalıştırırsam ve bir arka plan sekmesinde çalışmasına izin verirsem (yani, başka bir sekmeye geçip oraya göz atarsam), teste dönüp sonuçları inceleyerek (test bittiyse), önemli ölçüde değişir. Görünüşe göre zaman aşımları çok daha yavaş ilerliyor. FF4 veya IE9'da test edildiğinde bu gerçekleşmedi.setTimeout

Bu yüzden Chrome, odağı olmayan bir sekmede javascript yürütmeyi askıya alıyor veya en azından yavaşlatıyor gibi görünüyor. Konu hakkında internette pek bir şey bulamadık. Bu, örneğin XHR çağrılarını kullanarak bir sunucuda periyodik olarak kontrol etmek gibi arka plan görevlerini çalıştıramayacağımız anlamına gelir ve setInterval(aynı davranışı gördüğümden şüpheleniyorum setInterval, eğer zaman benimle ise bir test yazacaktır).

Bununla karşılaşan var mı? Bu askıya alma / yavaşlama için bir çözüm var mı? Buna bir hata der misiniz ve bu şekilde dosyalamalı mıyım?


İlginç! Sekmeye yeniden eriştiğinizde Chrome'un zamanlayıcıyı duraklatıp devam ettirdiğini veya yeniden başlattığını anlayabilir misiniz? Yoksa davranış rastgele mi? Chrome'un sekmeleri bağımsız süreçlerde çalıştırmasıyla bir ilgisi olabilir mi?
HyderA

@gAMBOOKa: @ pimvdb'nin cevabına bir göz atın. Saniyede maksimum bir yavaşlama olasılığı yüksektir.
KooiInc

4 yıl sonra ve bu sorun hala var. A ile div'ler için bir setTimeOut'ım var transition, bu nedenle tüm div'ler aynı anda geçiş yapmıyor, ancak aslında birbirinden 15ms sonra, bazı yuvarlanma efekti yaratıyor. Başka bir sekmeye gidip bir süre sonra geri döndüğümde, tüm div'ler aynı anda geçiş yapıyor ve setTimeOuttamamen yok sayılıyor. Projem için büyük bir sorun değil ama tuhaf ve istenmeyen bir eklenti.
Rvervuurt

Bir sırayla setTimeout adlı animasyonumuz için, bizim için çözüm sadece zamanlayıcının tanıtıcısını / kimliğini hatırladığımızdan emin olmaktı (setTimeout'tan döndü) ve yeni bir zamanlayıcı ayarlamadan önce ilk olarak clearTimeout'u çağırırsak tutacağı var. Bizim durumumuzda bu, sekmeye geri döndüğünüzde, hangi animasyonun oynadığı konusunda başlangıçta bazı tuhaflıklar olabileceği, ancak oldukça hızlı bir şekilde sıralanacağı ve normal animasyonun devam ettiği anlamına gelir. Bunun başlangıçta kodsuz bir sorun olduğunu düşünmüştük.
Eylem Dan

Yanıtlar:


89

Geçenlerde bunu sordum ve tasarım gereği davranış. Bir sekme etkin olmadığında, yalnızca en fazla saniyede bir işlev çağrılır. İşte kod değişikliği .

Belki bu yardımcı olur: Chrome'da bir sekme etkin olmadığında setInterval'in de çalışmasını nasıl sağlayabilirim?

TL; DR: Web Çalışanlarını kullanın .


3
teşekkürler, 'etkin olmayan sekme' ile bakmalıydım. Ana dili İngilizce olmamak bazen bir handikaptır.
KooiInc

1
@Kooilnc: Sorun değil :) Ana dili İngilizce olan biri de değilim.
pimvdb

22

Web Çalışanları kullanmanın bir çözümü var çünkü bunlar ayrı bir süreçte çalışıyor ve yavaşlamıyor

Kodunuzda değişiklik yapmadan kullanılabilecek küçük bir komut dosyası yazdım - sadece setTimeout, clearTimeout, setInterval, clearInterval işlevlerini geçersiz kılar

Sadece tüm kodunuzun önüne ekleyin

http://github.com/turuslan/HackTimer


7
Bu güzel ve hepsi ancak şunu unutmayın: 1. Çalışanların DOM'a erişimi yoktur, 2. Çalışanlar yalnızca kendi başlarına bir dosya üzerindeyken idam edilirler. Bu var olmayan bir açılan yerine setTimeout için vakaların bir sürü için.
Madara'nın Hayaleti

1
Haklısınız, ancak bazı modern tarayıcılar, Bloblar ( html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers ) kullanarak çalışanları kendi dosyaları olmadan kullanmalarına izin veriyor
Ruslan Tushov

1
Bununla bile, Web Çalışanları, setTimeout ve co için güvenli bir ikame olmalarını sağlayan pek çok işlevsellikten (yani DOM) yoksundur.
Madara's Ghost

Ön uçta çalışması gereken kodlara ne dersiniz? Örneğin, başka şeyler yaparken bitirmek istediğimiz ağır grafik işleme görevleri?
Michael

İşçiler, hizmet çalışanları oluşturabilir ve bir veri url'si kullanarak tuval API'sini kullanabilirsiniz. new Worker('data:text/javascript,(' + function myWorkerCode () { /*...*/ } + '()'). Ayrıca, ithalat ifadesi desteğiniz olup olmadığını kontrol etmenin de güzel bir yolu:try { eval('import("data:text/javascript,void 0")') } catch (e) { /* no support! */ }
Fábio Santos

9

Boş bir sesin çalınması, tarayıcıyı performansı korumaya zorluyor - Bu yorumu okuduktan sonra keşfettim: JavaScript, sekme etkin değilken bile Chrome'da normal hızda nasıl çalıştırılır?

WebSockets kullanan bir tarayıcı oyunu için isteğe bağlı sınırsız performansa ihtiyacım var, bu nedenle deneyimlerimden WebSockets kullanmanın sınırsız performans sağlamadığını biliyorum, ancak testlerden bir ses dosyası oynatmak bunu garantilemiş gibi görünüyor

İşte bu amaçla oluşturduğum 2 boş ses döngüsü, bunları ticari olarak özgürce kullanabilirsiniz: http://adventure.land/sounds/loops/empty_loop_for_js_performance.ogg http://adventure.land/sounds/loops/empty_loop_for_js_performance.wav

(-58db gürültü içerirler, -60db çalışmaz)

Bunları kullanıcı isteğine bağlı olarak Howler.js ile oynuyorum: https://github.com/goldfire/howler.js

function performance_trick()
{
    if(sounds.empty) return sounds.empty.play();
    sounds.empty = new Howl({
        src: ['/sounds/loops/empty_loop_for_js_performance.ogg','/sounds/loops/empty_loop_for_js_performance.wav'],
        volume:0.5,
        autoplay: true, loop: true,
    });
}

Tam javascript performansını varsayılan olarak açmak / kapatmak için yerleşik bir yöntem olmaması üzücü, ancak kripto madencileri herhangi bir uyarı olmadan Web Çalışanları kullanarak tüm bilgi işlem iş parçacıklarınızı ele geçirebilir: |


Teşekkürler, 58db kulaklıklarla çok duyulabilir, ancak siteyi sessize almak bu sorunu çözer
Kaan Soral

1

Chrome, Firefox ve IE için etkin olmayan sekmelerde çalışmaya devam etmek için Web-Workers'ı kullanarak Interval ve clearInterval uygulamasını ayarlayan işçi aralığı npm paketini yayınladım .

Modern tarayıcıların çoğu (Chrome, Firefox ve IE), aralıklar (pencere zamanlayıcıları), etkin olmayan sekmelerde saniyede bir defadan fazla çalışmayacak şekilde sabitlenir.

Hakkında daha fazla bilgi bulabilirsiniz

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Timeouts_and_intervals


0

JQuery çekirdeğimi 1.9.1'e güncelledim ve etkin olmayan sekmelerdeki Aralık tutarsızlığını çözdü. Önce bunu deneyeceğim, sonra diğer kod geçersiz kılma seçeneklerine bakardım.


hangi sürümden yükselttiniz? ~ 1.6
dmi3y

0

İşte mevcut milisaniyeyi alan ve bunu fonksiyonun oluşturulduğu milisaniye ile karşılaştıran benim çözümüm. aralık için, işlevi çalıştırdığında milisaniyeyi güncelleyecektir. ayrıca bir id ile aralığı / zaman aşımını yakalayabilirsiniz.

<script>

var nowMillisTimeout = [];
var timeout = [];
var nowMillisInterval = [];
var interval = [];

function getCurrentMillis(){
    var d = new Date();
    var now = d.getHours()+""+d.getMinutes()+""+d.getSeconds()+""+d.getMilliseconds();
    return now;
}

function setAccurateTimeout(callbackfunction, millis, id=0){
    nowMillisTimeout[id] = getCurrentMillis();
    timeout[id] = setInterval(function(){ var now = getCurrentMillis(); if(now >= (+nowMillisTimeout[id] + +millis)){callbackfunction.call(); clearInterval(timeout[id]);} }, 10);
}

function setAccurateInterval(callbackfunction, millis, id=0){
    nowMillisInterval[id] = getCurrentMillis();
    interval[id] = setInterval(function(){ var now = getCurrentMillis(); if(now >= (+nowMillisInterval[id] + +millis)){callbackfunction.call(); nowMillisInterval[id] = getCurrentMillis();} }, 10);
}

//usage
setAccurateTimeout(function(){ console.log('test timeout'); }, 1000, 1);

setAccurateInterval(function(){ console.log('test interval'); }, 1000, 1);

</script>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.