JavaScript setTimeout()은 부하가 높을 때 속도가 느려집니다.
-
05-07-2019 - |
문제
요소의 배경색을 흐리게 하는 스크립트를 만들었습니다.나는 5ms마다 색상을 점진적으로 변경하기 위해 setTimeout()을 사용합니다.한 번에 한 가지의 배경색을 페이드하는 경우에는 스크립트가 훌륭하게 작동하지만, 예를 들어 50개 요소가 동시에 모두 페이드되는 경우에는 속도가 5ms보다 훨씬 느립니다. 동시에 실행되는 동시 setTimeout().예를 들어, 일반적으로 1초 안에 실행되어야 하는 페이드는 한 번에 50개의 요소를 페이드하는 경우 30초가 걸릴 수 있습니다.
이 문제를 어떻게 극복할 수 있는지 아이디어가 있나요?
누군가 아이디어가 있는 경우를 대비해 스크립트는 다음과 같습니다.
function fadeBackground(elementId, start, end, time) {
var iterations = Math.round(time / 5);
var step = new Array(3);
step[0] = (end[0] - start[0]) / iterations;
step[1] = (end[1] - start[1]) / iterations;
step[2] = (end[2] - start[2]) / iterations;
stepFade(elementId, start, step, end, iterations);
}
function stepFade(elementId, cur, step, end, iterationsLeft) {
iterationsLeft--;
document.getElementById(elementId).style.backgroundColor
= "rgb(" + cur[0] + "," + cur[1] + "," + cur[2] + ")";
cur[0] = Math.round(end[0] - step[0] * iterationsLeft);
cur[1] = Math.round(end[1] - step[1] * iterationsLeft);
cur[2] = Math.round(end[2] - step[2] * iterationsLeft);
if (iterationsLeft > 1) {
setTimeout(function() {
stepFade(elementId, cur, step, end, iterationsLeft);
}, 5);
}
else {
document.getElementById(elementId).style.backgroundColor
= "rgb(" + end[0] + "," + end[1] + "," + end[2] + ")";
}
}
다음과 같이 사용됩니다:
fadeBackground("myList", [98,180,232], [255,255,255], 1000);
해결책
여기는 기사 저자가 Gmail 타이머에 대한 작업을 논의하는 Google의 글입니다.그들은 타이머를 많이 사용하고 빠른 경우 여러 개의 타이머를 사용하는 것보다 단일 고주파 타이머를 사용하는 것이 더 빠르다는 것을 발견했습니다.
5ms마다 실행되는 하나의 타이머를 갖고 페이딩 프로세스의 위치를 추적하는 데이터 구조에 페이드해야 하는 모든 요소를 추가할 수 있습니다.그러면 하나의 타이머가 해당 목록을 살펴보고 트리거될 때마다 각 요소에 대해 다음 페이드를 수행할 수 있습니다.
반면에 다음과 같은 라이브러리를 사용해 보셨나요? 무툴즈 또는 제이쿼리 자신만의 애니메이션 프레임워크를 롤링하는 것보다?개발자들은 이러한 종류의 작업을 최적화하기 위해 많은 노력을 기울였습니다.
다른 팁
우선 스크립트는 최소 타임 아웃이 브라우저에 따라 10-15ms라는 점을 고려하지 않습니다. 너는 볼 수있어 이 주제에 대한 내 게시물. 내부에는 인기있는 브라우저를위한 테이블과이를 측정하는 프로그램 링크가 있으므로 클레임을 직접 확인할 수 있습니다. 미안하지만 5ms마다 반복은 희망적인 생각입니다.
둘째, 타이머는 인터럽트가 아닙니다. 그들 안에는 마법이 없습니다. 브라우저에서 실행중인 모든 것을 방해하고 페이로드를 실행할 수 없습니다. 대신 실행중인 코드가 완료되고 브라우저가 컨트롤과 타이머를 실행하는 기능을 되 찾을 때까지 연기 될 것입니다. 페이딩 50 요소는 시간이 걸리며, 특히 브라우저의 전체 지연된 모델을 고려하면 DOM을 업데이트하면 브라우저가 시각적 표현을 업데이트합니다.
긍정적 인 메모로 마무리하고 싶습니다 :
- 50 개의 개별 요소를 사라지는 대신 그룹을 그룹화하고 부모를 사라집니다. 더 빠를 수 있습니다.
- UI에서 더 창의적입니다. 한 번에 많은 독립적 인 요소를 퇴색 할 필요가없는 솔루션을 생각해 내십시오.
- 항상 배경 가정이 그 주위를 설계하기 전에 정확한지 확인하십시오.
- 가능하다면 최신 브라우저를 타겟팅하십시오. 내 개인적인 경험에서 Google Chrome은 타이머에 매우 능숙하며 JavaScript 엔진 (V8)은 매우 빠릅니다.
다른 답변 외에도 John Resig의 훌륭한 기사는 다음과 같습니다. http://ejohn.org/blog/how-javascript-timers-work/