sourcecode

탭이나 윈도우가 활성화되어 있지 않을 때 브라우저는 자바스크립트를 어떻게 일시정지/변경합니까?

copyscript 2023. 9. 6. 22:14
반응형

탭이나 윈도우가 활성화되어 있지 않을 때 브라우저는 자바스크립트를 어떻게 일시정지/변경합니까?

배경:저는 사람들이 주의를 기울이고 있는지 아닌지를 감지하기 위해 몇 가지 사용자 인터페이스 테스트를 하고 있습니다.그러나 이 질문은 페이지 가시성 API에 관한 이 아닙니다.

구체적으로 현재 탭이 활성화되어 있지 않거나 브라우저 창이 활성화되어 있지 않을 경우 브라우저마다 제 자바스크립트 코드가 어떤 영향을 받는지 알고 싶습니다.저는 지금까지 다음과 같은 것들을 알아냈습니다.

다음과 같은 질문이 있습니다.

  • 모바일 브라우저 이외의 데스크톱 브라우저는 탭이 활성화되지 않을 때 JS 실행을 일시 중지한 적이 있습니까?언제, 어떤 브라우저?
  • 된 는 입니까를 줄인 는?setInterval◦? 로 축소하는 건가요?그것은 단지 제한으로 축소되는 것입니까 아니면 백분율로 축소되는 것인가요?예를 들어, 10ms 반복과 5000ms 반복이 있을 경우 각각 어떤 영향을 받습니까?
  • 탭이 아닌 창에 초점이 맞지 않을 경우 이러한 변경 사항이 발생합니까?(OS API가 필요하기 때문에 감지하기가 더 어려울 것으로 예상됩니다.
  • 활성 탭에서 관찰되지 않는 다른 효과가 있습니까?그렇지 않으면 올바르게 실행될 수 있는 일을 망칠 수 있습니까(예: 앞서 언급한 재스민 테스트)?

테스트 원

이를 위해 특별히 테스트를 작성했습니다.
분포 : vs request AnimationFrame : setInterval vs request AnimationFrame

참고: 이 테스트는 CPU 집약적입니다.requestAnimationFrameIE 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( 에 대해서도 동일해야 합니다.setInterval1000ms 미만 대기는 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

반응형