2015-02-08 25 views
9

Mam do czynienia z wysokim obciążeniem procesora (od 30 do 40%) podczas wywoływania rekursywnie requestAnimationFrame, czy ktoś ma dobre strategie, aby go obniżyć?Wysokie użycie procesora z płótnem i requestAnimationFrame

Prosty przykład:

var canvas = document.createElement('canvas'); 
 
canvas.width = 100; 
 
canvas.height = 20; 
 

 
var canvasContext = canvas.getContext('2d'); 
 
document.body.appendChild(canvas) 
 

 
var rafId; 
 
function drawLoop(time) { 
 
    canvasContext.clearRect(0, 0, 100, 20); 
 
    canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20); 
 
    rafID = window.requestAnimationFrame(drawLoop); 
 
} 
 

 
drawLoop();

+0

requestAnimationFrame() jest _supposed_, aby działać tak szybko, jak to możliwe, a tym samym używać dużo CPU. jeśli potrzebujesz mniej aktualizacji, użyj timera, aby zamiast tego kierować się rozsądnym współczynnikiem FPS. – dandavis

+1

@dandavis: Z tego co wiem 'requestAnimationFrame()' jest zwykle ograniczone do 60 FPS, a nie "tak szybko jak to możliwe": https://developer.mozilla.org/en-US/docs/Web/API/window .requestAnimationFrame - z 60 FPS lub więcej powinieneś mieć dużo czasu na małe aktualizacje na '' bez maksymalizacji CPU –

+1

@Laurent - wypróbuj różne przeglądarki i urządzenia. Twój kod rysunkowy jest tak prosty, że powinien obezwładnić tylko bardzo słaby komputer, chyba że są pewne problemy (brak przyspieszenia HW itp.). –

Odpowiedz

2

nie mogę dostać tego przykładu, aby zrobić coś do mojego procesora warto wspomnieć, ale udało nam się dostać go w dół przez zastosowanie tych dwóch metod. Mój procesor działał na poziomie około 4-5% z uruchomionym urywkiem, uruchamiając zapis/przywracanie w kontekście, który zgasił 2%. Nie wiem, dlaczego - ponieważ nie dokonaliśmy żadnych transformacji. Ten ostatni przykład tylko używa starej hakerów sposób to zrobić poprzez zresetowanie canvas.width - to wyciera cały kontekst płótno za każdym razem - i powinny być droższe - ale to ma ten przykład w dół do 1,4%

var canvas = document.createElement('canvas'); 
 
canvas.width = 100; 
 
canvas.height = 20; 
 

 
var canvasContext = canvas.getContext('2d'); 
 
document.body.appendChild(canvas) 
 

 
var rafId; 
 
function drawLoop(time) { 
 
    canvasContext.save(); 
 
    canvasContext.clearRect(0, 0, 100, 20); 
 
    canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20); 
 
    canvasContext.restore(); 
 
    rafID = window.requestAnimationFrame(drawLoop); 
 
} 
 

 
drawLoop();
var canvas = document.createElement('canvas'); 
 
canvas.width = 100; 
 
canvas.height = 20; 
 

 
var canvasContext = canvas.getContext('2d'); 
 
document.body.appendChild(canvas) 
 

 
var rafId; 
 
function drawLoop(time) { 
 
    canvas.width = canvas.width; 
 
    canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20); 
 
    rafID = window.requestAnimationFrame(drawLoop); 
 
} 
 

 
drawLoop();

teraz musiałbym iść do dalszych poszukiwań wydajności, aby dowiedzieć się dlaczego, czy to faktycznie nic nie robi w ogóle.

Można jednak zastosować inną technikę rysowania, np. Po prostu przesuwanie ikonki lub maski w niektórych danych bitmapowych, co znacznie utrudnia obsługę renderera. Nie będę tego publikował, ponieważ wykracza to poza zakres tego pytania.