Chrome : 백그라운드 탭에서 시간 초과 / 간격이 일시 중지 되었습니까?


130

이 테스트setTimeout사용 하는 정확성을 테스트하고있었습니다 . 이제는 (예상대로) 매우 정확하지는 않지만 대부분의 기기에서 크게 부정확하지 않은 것으로 나타났습니다 . 이제 Chrome에서 테스트를 실행하고 백그라운드 탭에서 실행하면 (다른 탭으로 전환하여 검색) 테스트로 돌아가서 결과를 검사 (테스트가 완료된 경우)하면 크게 변경됩니다. 시간 초과가 훨씬 느리게 실행 된 것 같습니다. FF4 또는 IE9에서 테스트되었지만 이러한 현상이 발생하지 않았습니다.setTimeout

따라서 Chrome에서 포커스가없는 탭에서 자바 스크립트 실행이 일시 중단되거나 적어도 느려집니다. 인터넷에서 주제를 많이 찾을 수 없습니다. 우리가 예 XHR 호출을 사용하여 서버에 주기적으로 확인하고 위해 같은 백그라운드 작업을 실행할 수 있음을 의미한다 setInterval(I가 동일한 동작을 볼 수 의심 setInterval시간을 나와 함께있는 경우 테스트를 작성합니다).

누구든지 이것을 만난 적이 있습니까? 이 일시 중지 / 지연에 대한 해결 방법이 있습니까? 버그라고 부르시겠습니까?


흥미 롭습니다! 탭에 다시 액세스하면 Chrome에서 일시 중지했다가 다시 시작하는지 또는 다시 시작하는지 알 수 있습니까? 아니면 행동이 무작위입니까? Chrome이 독립 프로세스에서 탭을 실행한다는 사실과 관련이 있습니까?
HyderA

@gAMBOOKa : @ pimvdb의 답변을 살펴보십시오. 초당 최대 한 번으로 느려질 수 있습니다.
KooiInc

4 년 후에도이 문제는 여전히 존재합니다. 와 함께 div에 대해 setTimeOut이 transition있으므로 모든 div가 동시에 전환되는 것은 아니지만 실제로 15ms가 지나면 롤링 효과가 발생합니다. 다른 탭으로 이동하고 잠시 후 다시 돌아 오면 모든 div가 동시에 전환되고 setTimeOut가 완전히 무시됩니다. 내 프로젝트에는 큰 문제는 아니지만 이상하고 원치 않는 추가 사항입니다.
Rvervuurt

시퀀스에서 setTimeout을 호출 한 애니메이션의 경우 해결책은 타이머의 핸들 / ID (setTimeout에서 반환 됨)를 기억하고 새 타이머를 설정하기 전에 먼저 clearTimeout을 호출하는 것입니다. 손잡이를 얻었다. 우리의 경우 이것은 탭으로 돌아올 때 어떤 애니메이션이 재생되고 있는지에 대한 초기의 괴로움이있을 수 있지만 꽤 빨리 정리되고 일반 애니메이션이 다시 시작됨을 의미합니다. 우리는 이것이 코드가 처음에는 문제라고 생각했습니다.
액션 Dan

답변:


88

나는 최근에 이것에 대해 물었고 그것은 의도적으로 행동입니다. 탭이 비활성화되면 초당 최대 한 번만 함수가 호출됩니다. 다음은 코드 변경 입니다.

아마도 이것이 도움이 될 것입니다 : Chrome에서 탭이 비활성 상태 일 때 setInterval을 작동시키는 방법은 무엇입니까?

TL; DR : 웹 워커 사용 .


3
고마워, 나는 '비활성 탭'으로보아야했습니다. 영어를 모국어로 사용하지 않는 것은 때때로 장애입니다.
KooiInc

1
@ Kooilnc : 문제 없습니다 :) 나는 영어 원어민도 아닙니다.
pimvdb

22

웹 워커는 별도의 프로세스에서 실행되며 속도가 느려지지 않기 때문에 사용할 수있는 솔루션이 있습니다.

코드를 변경하지 않고 사용할 수있는 작은 스크립트를 작성했습니다 .setTimeout, clearTimeout, setInterval, clearInterval 함수를 무시합니다.

모든 코드 앞에 포함하십시오

http://github.com/turuslan/HackTimer


7
1. 노동자는 DOM에 액세스 할 수 없습니다. 2. 노동자는 자신의 파일에있는 경우에만 처형됩니다. 그건 하지 드롭 인 교체의 setTimeout에 대한 많은 경우에.
Madara의 유령

1
당신은 옳지 만 일부 최신 브라우저에서는 Blob ( html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers ) 을 사용하여 자신의 파일없이 작업자를 사용할 수 있습니다
Ruslan Tushov

1
그럼에도 불구하고 웹 워커는 setTimeout 및 co를 안전하게 대체 할 수있는 많은 기능 (DOM)이 누락되었습니다.
Madara 's Ghost

프론트 엔드에서 실행해야하는 코드 (예 : 다른 작업을 수행하는 동안 완료하려는 무거운 그래픽 처리 작업)는 어떻습니까?
Michael

글쎄, 당신은 worker를 만들고, service worker를 사용하여 canvas API를 사용할 수 있습니다. new Worker('data:text/javascript,(' + function myWorkerCode () { /*...*/ } + '()'). 임포트 표현식 지원이 있는지 확인하는 좋은 방법이기도합니다.try { eval('import("data:text/javascript,void 0")') } catch (e) { /* no support! */ }
Fábio Santos

9

~ 빈 사운드를 재생하면 브라우저가 성능을 유지하도록 강요-이 주석을 읽은 후 발견했습니다. 탭이 활성화되지 않은 경우에도 Chrome에서 JavaScript를 정상 속도로 실행하는 방법은 무엇입니까?

WebSockets를 사용하는 브라우저 게임에는 주문형 성능이 필요하므로 WebSocket을 사용한다고해서 성능이 제한되지는 않지만 경험을 통해 오디오 파일을 재생하면 오디오 파일을 재생할 수 있습니다.

여기에 상업적으로, 나는이 목적을 위해 만든이 빈 오디오 루프, 당신은 자유롭게 사용할 수있다 : http://adventure.land/sounds/loops/empty_loop_for_js_performance.ogg http://adventure.land/sounds/loops/empty_loop_for_js_performance.wav

(-58db 노이즈를 포함하고 -60db가 작동하지 않습니다)

Howler.js를 사용하여 사용자 요구에 따라 재생합니다. 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,
    });
}

기본적으로 전체 자바 스크립트 성능을 켜고 끄는 내장 된 방법이 없다는 것은 슬픈 일이지만, 암호 채굴자는 프롬프트없이 웹 워커를 사용하여 모든 컴퓨팅 스레드를 가로 챌 수 있습니다. |


감사합니다. 58db는 헤드폰으로도들을 수 있지만 사이트를 음소거하면 문제가 해결됩니다.
Kaan Soral

1

Chrome, Firefox 및 IE의 비활성 탭을 유지하고 실행하기 위해 Web-Workers를 사용하여 interInterval 및 clearInterval 구현을 설정하는 worker-interval npm 패키지를 출시했습니다 .

대부분의 최신 브라우저 (Chrome, Firefox 및 IE), 간격 (창 타이머)은 비활성 탭에서 초당 1 회 이상 실행되도록 고정되어 있습니다.

당신은 더 많은 정보를 찾을 수 있습니다

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 코어를 1.9.1로 업데이트했으며 비활성 탭의 간격 불일치를 해결했습니다. 먼저 시도한 다음 다른 코드 재정의 옵션을 살펴보십시오.


어떤 버전에서 업그레이드 했습니까? 나는 ~ 1.6 버전과 약간의 타임 아웃 문제 (갤러리 슬라이더를) 경험
dmi3y을

0

여기에 현재 밀리 초를 가져 와서 함수가 작성된 밀리 초와 비교하는 솔루션이 있습니다. 간격 동안 함수를 실행할 때 밀리 초를 업데이트합니다. ID로 간격 / 시간 초과를 파악할 수도 있습니다.

<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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.