EDIT : Firefox에서만 발생합니다! (22.0을 사용하고 있습니다.) 하단의 브라우저 비교를보십시오.파이어 폭스에 대한 재귀 호출이
픽셀 데이터를 복사하고 점진적으로 알파 값을 255에서 0으로 변경하면 (배경이 검은 색) 캔버스에 '검은 색 페이드'효과를 만들려고합니다.
function fadeToBlack() {
if(typeof this.recursion === 'undefined' || this.recursion === 0) {
this.recursion = 1;
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.imageDataArray = this.imageData.data;
this.pixelCount = this.imageDataArray.length/4;
this.fadeToBlack();
}
else if (this.recursion <= 15){
console.time('Change alpha ' + this.recursion);
for (var i = 0; i < this.pixelCount; i++){
this.imageDataArray[i * 4 + 3] = 255 - 255/15 * this.recursion;
}
console.timeEnd('Change alpha ' + this.recursion);
this.ctx.putImageData(this.imageData, 0, 0);
this.recursion++;
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 50);
}
else {
this.recursion = 0;
}
};
나는 (! 1280 * 1024 = 1310720 반복)이 정말 비싼 것이라고 생각하지만, 아래의 콘솔 로그에서 볼 수 있듯이, 그것은 첫 번째 반복을 제외하고 놀라 울 정도로 빨랐다. 단순히
fadeToBlack
(화소 조작 첫번째 반복)의 두 번째 반복 ... 지연 경우
Change alpha 1: 543ms
Change alpha 2: 16ms
Change alpha 3: 6ms
Change alpha 4: 16ms
...
이상하게 마법
function fadeToBlack() {
if(typeof this.recursion === 'undefined' || this.recursion === 0) {
this.recursion = 1;
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.imageDataArray = this.imageData.data;
this.pixelCount = this.imageDataArray.length/4;
//This is the only difference!
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 0);
}
else if (this.recursion <= 15){
console.time('Change alpha ' + this.recursion);
for (var i = 0; i < this.pixelCount; i++){
this.imageDataArray[i * 4 + 3] = 255 - 255/15 * this.recursion;
}
console.timeEnd('Change alpha ' + this.recursion);
this.ctx.putImageData(this.imageData, 0, 0);
this.recursion++;
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 50);
}
else {
this.recursion = 0;
}
};
뭔가 일어난다.
Change alpha 1: 16ms
Change alpha 2: 16ms
Change alpha 3: 6ms
Change alpha 4: 6ms
...
그래서 도대체 무슨 일이 벌어지고있는거야?
EDIT : 나는 여러 브라우저에서이를 테스트했으며, 15 회 반복마다 밀리 초 단위로 결과를 보았습니다.
Browser |Recursive |Asynchronous
=========+===========+============
Firefox |1652† |1136
Chrome |976 |978
Opera |12929 |13855
IE |855 |854
첫 번째 반복 매우 비용 (500ms로)이었다 †.
이후 백그라운드에서. 다시는 재귀가 아닙니다. 반환하는 값에 의존하지 않아도됩니다. 그 부스트의 이유를 알고 싶습니다. 비동기 호출을 호출하고 메모리에서 현재를 제거하고 대기열과 관련이없는 것으로 간주하는 현재 호출을 마칠 때입니까? – CME64
질문을 던질 때 비동기식/재귀형에 조금 퍼지기는했지만 지금은 조금 읽었습니다 ... 성능 향상이 어디에서 발생하는지 아직 알지 못합니다. 나는 아마도 같은 엔진에서 동일한 5mB 데이터 세트 (this.imageData)에 동시에 액세스 할 수있는 2 개의 함수를 사용하는 것과 관련이 있습니다. 다른 브라우저에서 몇 가지 테스트를 수행하고 어떤 결과가 발생하는지 볼 수 있습니다. – LittleJohn
@ CME64 완료! 확실히 엔진 버릇처럼 보입니다! – LittleJohn