탭이나 윈도우가 활성화되어 있지 않을 때 브라우저는 자바스크립트를 어떻게 일시정지/변경합니까?
배경:저는 사람들이 주의를 기울이고 있는지 아닌지를 감지하기 위해 몇 가지 사용자 인터페이스 테스트를 하고 있습니다.그러나 이 질문은 페이지 가시성 API에 관한 것이 아닙니다.
구체적으로 현재 탭이 활성화되어 있지 않거나 브라우저 창이 활성화되어 있지 않을 경우 브라우저마다 제 자바스크립트 코드가 어떤 영향을 받는지 알고 싶습니다.저는 지금까지 다음과 같은 것들을 알아냈습니다.
- 탭이 활성화되지 않은 경우 ios 5가 javascript를 일시 중지합니다.
setInterval
탭이 활성화되어 있지 않을 때 지연이 줄어듭니다. 최근에 이런 현상이 나타나기 시작해서 재스민 단위 테스트 등을 엉망으로 만들 수 있습니다.requestAnimationFrame
되어 있지 는 느려집니다(너무 할 수 없습니다).어을때다만지이무게큰을다할는를수른이s다할수를만ds는nb을큰(n무e이tef(nod
다음과 같은 질문이 있습니다.
- 모바일 브라우저 이외의 데스크톱 브라우저는 탭이 활성화되지 않을 때 JS 실행을 일시 중지한 적이 있습니까?언제, 어떤 브라우저?
- 된 는 입니까를 줄인 는?
setInterval
◦? 로 축소하는 건가요?그것은 단지 제한으로 축소되는 것입니까 아니면 백분율로 축소되는 것인가요?예를 들어, 10ms 반복과 5000ms 반복이 있을 경우 각각 어떤 영향을 받습니까? - 탭이 아닌 창에 초점이 맞지 않을 경우 이러한 변경 사항이 발생합니까?(OS API가 필요하기 때문에 감지하기가 더 어려울 것으로 예상됩니다.
- 활성 탭에서 관찰되지 않는 다른 효과가 있습니까?그렇지 않으면 올바르게 실행될 수 있는 일을 망칠 수 있습니까(예: 앞서 언급한 재스민 테스트)?
테스트 원
이를 위해 특별히 테스트를 작성했습니다.
분포 : vs request AnimationFrame : setInterval vs request AnimationFrame
참고: 이 테스트는 CPU 집약적입니다.requestAnimationFrame
IE 9- 및 Opera 12-에서는 지원되지 않습니다.
테스트는 실제 시간을 기록합니다.setInterval
그리고.requestAnimationFrame
다른 브라우저에서 실행되며 결과를 배포 형식으로 제공합니다.초를할수다한r수l에 대한 밀리초 수를 변경할 수 .setInterval
다른 설정에서 어떻게 실행되는지 확인합니다.setTimeout
와게합니다.setInterval
지연에 관해서는requestAnimationFrame
는 브라우저에 따라 일반적으로 60인치로 기본 설정됩니다.다른 탭으로 전환하거나 비활성 창이 있을 때 어떻게 되는지 보려면 페이지를 열고 다른 탭으로 전환한 후 잠시 기다리기만 하면 됩니다.비활성 탭에서 이러한 기능에 소요되는 실제 시간을 계속 기록합니다.
테스트 투
테스트하는 또 다른 방법은 타임스탬프를 다음과 같이 반복적으로 기록하는 것입니다.setInterval
그리고.requestAnimationFrame
분리된 콘솔에서 볼 수 있습니다.탭이나 창을 비활성화할 때 업데이트되는 빈도(또는 업데이트된 적이 있는지 여부)를 확인할 수 있습니다.
결과.
은 최소 은을다e을 제한합니다.setInterval
탭이 비활성 상태일 때 약 1000ms로 이동합니다.간격이 1000ms보다 높으면 지정된 간격으로 실행됩니다.창이 포커스를 벗어나도 상관없으며, 간격은 다른 탭으로 전환할 때만 제한됩니다.requestAnimationFrame
탭이 비활성화되면 일시 중지됩니다.
// Provides control over the minimum timer interval for background tabs.
const double kBackgroundTabTimerInterval = 1.0;
https://codereview.chromium.org/6546021/patch/1001/2001
파이어폭스
Chrome과 는 Chrome하게 Firefox소다을과의 최소 합니다.setInterval
탭(윈도우가 아님)이 비활성 상태일 때 약 1000ms로 이동합니다.만,requestAnimationFrame
탭이 비활성 상태일 때 기하급수적으로 느리게 실행되며, 각 프레임은 1초, 2초, 4초, 8초 등이 걸립니다.
// The default shortest interval/timeout we permit
#define DEFAULT_MIN_TIMEOUT_VALUE 4 // 4ms
#define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms
https://hg.mozilla.org/releases/mozilla-release/file/0bf1cadfb004/dom/base/nsGlobalWindow.cpp#l296
Internet Explorer
는 IE을지다서에서 .setInterval
상태이지만 중지되는 이성시는우만우는nrequestAnimationFrame
비액티브 탭을 선택합니다.창이 초점을 벗어나든 그렇지 않든 상관없습니다.
가장자리
14,지 14해서부터,setInterval
는 비활성 탭에서 1000ms로 제한됩니다.requestAnimationFrame
비활성 탭에서는 항상 일시 중지됩니다.
도 Chrome, Safari를 합니다.과setInterval
탭이 비활성 상태일 때 1000ms에서.requestAnimationFrame
역시 일시 중지됩니다.
웹킷 엔진이 채택된 이후 오페라는 크롬과 같은 동작을 보여줍니다.setInterval
및 1,000ms ㎠로 됩니다.requestAnimationFrame
탭이 비활성화되면 일시 중지됩니다.
요약
비활성 탭에 대한 반복 간격:
setInterval request애니메이션프레임크롬9 - 영향을 받지 않음 지원되지 않음10 영향을 받지 않음 일시 중지됨11+ >= 1000ms 일시정지 파이어폭스3- 영향을 받지 않음 지원되지 않음영향을 받지 않는 4개의 1개5+ > = 1000ms 2s (n = 비활성화 이후 프레임 수) IE9 - 영향을 받지 않음 지원되지 않음10+ 해당되지 않음 일시 중지됨 가장자리13- 해당되지 않음 일시 중지됨14+ >= 1000ms 일시정지 사파리5- 수수료 없음ct가 지원되지 않음6 영향을 받지 않음 일시 중지됨7+ >= 1000ms 일시정지 오페라12- 영향을 받지 않음 지원되지 않음15+ >= 1000ms 일시정지
관찰한 내용: Chrome의 비활성 탭에서, 당신의 모든 것.setTimeout
( 에 대해서도 동일해야 합니다.setInterval
1000ms 미만 대기는 1000ms로 반올림됩니다.더 긴 타임아웃은 수정되지 않은 것 같습니다.
Chrome 11과 Firefox 5.0 이후의 동작으로 보입니다 : https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs
또한 전체 창이 비활성 상태일 때는 이와 같이 동작하지 않는다고 생각합니다(그러나 조사하기는 꽤 쉬운 것 같습니다).
이를 보완하기 위한 새로운 답변: 크롬 78.0.3904.108에서 다른 탭으로 이동할 때 예상보다 시간 초과(1000ms 미만이 아닌) 시간 초과가 조금 더 걸리는 것을 알 수 있습니다.현재 보고 있는 동작은 "비활성 탭의 모든 시간 초과가 최대 1000ms까지 추가로 지연될 수 있습니다."라고 더 정확하게 설명됩니다.다음을 실행하고 다른 탭으로 전환해 보십시오!
let timeouts = [ 500, 1000, 2000, 3000, 10000 ];
let minExcess = document.getElementsByClassName('minExcess')[0];
timeouts.forEach(ms => {
let elem = document.getElementsByClassName(`t${ms}`)[0];
let cnt = 0;
let lastMs = +new Date();
let f = () => {
let curMs = +new Date();
let disp = document.createElement('p');
let net = curMs - lastMs;
lastMs = curMs;
setTimeout(f, ms);
if (minExcess.value && (net - ms) < parseInt(minExcess.value)) return;
disp.innerText = `${net},`;
elem.appendChild(disp);
if (++cnt > 10) elem.firstElementChild.remove();
};
setTimeout(f, ms);
});
body { font-size: 80%; }
div {
max-height: 80px;
overflow-x: auto;
background-color: rgba(0, 0, 0, 0.1);
margin-bottom: 2px;
white-space: nowrap;
}
p { margin: 0; }
div > p {
margin: 0;
display: inline-block;
vertical-align: top;
margin-right: 2px;
}
input { margin: 0 0 10px 0; }
.t500:before { display: block; content: '500ms'; font-weight: bold; }
.t1000:before { display: block; content: '1000ms'; font-weight: bold; }
.t2000:before { display: block; content: '2000ms'; font-weight: bold; }
.t3000:before { display: block; content: '3000ms'; font-weight: bold; }
.t10000:before { display: block; content: '10000ms'; font-weight: bold; }
<p>Ignore any values delayed by less than this amount:</p>
<input type="text" class="minExcess" value="200" pattern="^[0-9]*$"/>
<div class="timeout t500"></div>
<div class="timeout t1000"></div>
<div class="timeout t2000"></div>
<div class="timeout t3000"></div>
<div class="timeout t10000"></div>
언급URL : https://stackoverflow.com/questions/15871942/how-do-browsers-pause-change-javascript-when-tab-or-window-is-not-active
'sourcecode' 카테고리의 다른 글
로컬 컴퓨터에서 AWS의 MySQL에 연결 (0) | 2023.09.06 |
---|---|
PowerShell에서 Python 실행 (0) | 2023.09.06 |
Swift에서 옵션 다운캐스팅: as?타이프, or as!타입? (0) | 2023.09.06 |
두 선택 문 결합 (0) | 2023.09.06 |
발그린드로 유닛 테스트를 진행하는 것은 오버킬인가요? (0) | 2023.09.06 |