2012-03-22 8 views
6

Ho una pagina che ha operazioni piuttosto pesanti (piuttosto pesanti) canvas in corso. Per soddisfare gli utenti su dispositivi mobili e computer più vecchi pensavo che avrei potuto implementare un meccanismo che controllasse se l'elemento canvas è effettivamente visibile e decidere se i calcoli costanti e gli aggiornamenti canvas (animazione a 30fps) devono essere eseguiti o meno .I browser rendono gli elementi canvas che non si trovano all'interno del viewport?

Questo funziona perfettamente, ma quando eseguo un test delle prestazioni con Chrome Dev Tools ho notato che anche quando disattivo il controllo della visibilità e faccio in modo che le cose vengano sempre visualizzate, l'utilizzo della CPU della funzione in questione diminuisce un po ' quando nessuna parte degli elementi canvas è visibile (anche se in teoria dovrebbe comunque svolgere le stesse attività). Quindi: almeno sul mio computer con Chrome 17 non fa davvero la differenza se controllo la visibilità effettiva dell'elemento.

Per farla breve: ho bisogno di fare questo o i browser sono abbastanza intelligenti da gestire un caso del genere senza nemmeno dirlo (e posso salvare il controllo della visibilità)?


EDIT:

Così ho fatto qualche "ricerca" su questo argomento e costruito this fiddle.

Quello che succede è che si genera solo rumore a 30 fotogrammi al secondo. Non troppo piacevole alla vista ma, beh ... La parte superiore è solo un semplice div per bloccare il viewport. Quando si scorre verso il basso e l'elemento canvas nel Viewport CPU Usage mi dice che sta prendendo circa il 40%, quindi apparentemente il browser ha molto da fare qui. Quando faccio scorrere di nuovo verso l'alto in modo da avere solo il colore marrone rossastro div nel mio viewport e profilo l'utilizzo della CPU scende a sth circa il 10%. Quando scorro verso il basso: l'utilizzo aumenta nuovamente.

Così, quando a implementare un controllo di visibilità come in questo modified fiddle, faccio vedere un aumento (una minuscola ad essere onesti) in utilizzo della CPU al posto di una goccia (in quanto ha il compito supplementare di verificare se la tela è all'interno del viewport).

Quindi mi sto ancora chiedendo se questo è un effetto collaterale di qualcosa di cui non sono a conoscenza (o sto facendo un grosso errore durante la profilazione) o se posso aspettarmi che i browser siano abbastanza intelligenti da gestire tali situazioni?

Se qualcuno potesse far luce su questo sarei molto grato!

risposta

8

Penso che tu sia confuso tra se il logica è in esecuzione e se il rendendo sta accadendo. Molti browser ora accelerano l'hardware delle loro tele in modo che tutto il rendering avvenga sulla GPU, quindi l'effettiva spinta dei pixel non richiede comunque tempo CPU. Tuttavia la tua funzione tick ha un codice non banale per generare rumore casuale sulla CPU. Quindi ti preoccupi solo se la funzione tick funziona.Se la tela non è a schermo, sicuramente non verrà visualizzata sullo schermo (non è visibile). Per quanto riguarda le chiamate di disegno su tela, probabilmente dipende dal browser. Potrebbe eseguire il rendering di tutte le chiamate di disegno su una tela fuori schermo nel caso in cui lo si ritorchi all'improvviso per visualizzare, o potrebbe semplicemente accodare tutte le chiamate di disegno e in realtà non fare nulla con esse finché non si scorre la tela per visualizzare. Non sono sicuro di cosa faccia ogni browser.

Tuttavia, non si dovrebbe usare setInterval o setTimeout per l'animazione Canvas. Utilizza la nuova API requestAnimationFrame. I browser non sanno cosa fare in una chiamata programmata, quindi chiamerà sempre il timer. requestAnimationFrame d'altra parte è progettato specificamente per le cose visive, quindi il browser ha l'opportunità di non chiamare la funzione tick, o di ridurre la velocità a cui è chiamato, se la tela o la pagina non è visibile.

Per quanto riguarda il modo in cui i browser in realtà gestirlo, non sono sicuro. Tuttavia, dovresti sicuramente preferirlo dato che i futuri browser potrebbero essere in grado di ottimizzare al meglio requestAnimationFrame in modi che non possono ottimizzare setInterval o setTimeout. Penso che i browser moderni riducano anche i timer ordinari a 1 Hz se la pagina non è visibile, ma è decisamente molto più facile per il browser ottimizzare requestAnimationFrame, più alcuni browser ottengono la V-syncing e altre simpatie con esso.

Quindi non sono sicuro che lo requestAnimationFrame significherà che la funzione di spunta non viene chiamata se la tela viene spostata fuori dalla vista. Quindi mi consiglia di utilizzare siarequestAnimationFrame e il controllo di visibilità esistente. Questo dovrebbe garantire il rendering più efficiente.

+0

Wow, grazie mille per questa risposta super completa! Ho sentito parlare di 'requestAnimationFrame', ma quello che mi ha sempre infastidito è che sembra mirare all'animazione a 60fps, non importa quale (cosa che penso sia troppo liscia per molti tipi di animazione). L'unico modo per limitarlo mi viene in mente di includere ancora una volta "setInterval" .... Sai se esiste un modo per limitarlo/modificarlo? – m90

+0

troppo liscio? Non ho mai sentito di un'animazione troppo liscia, cosa c'è di sbagliato in questo? : S – AshleysBrain

+0

Potrebbe sembrare strano, eppure ho un background nell'animazione classica, quindi penso davvero a 12fps, pensare come se fosse parte del mio cervello ormai. La mia obiezione potrebbe essere sciocca nel 95% dei casi, ma per alcuni casi sarebbe fantastico avere più controllo. – m90

2

Dalla mia esperienza personale rende qualunque cosa tu dica di rendere indipendentemente dalla posizione sullo schermo.

Un esempio è se si disegnano riquadri, che supera le dimensioni dell'area di lavoro, si continuerà a vedere il calo delle prestazioni a meno che non si ottimizzi lo script.

Prova la tua funzione con un'animazione performante e verifica se ottieni ancora gli stessi risultati.

+0

Il calo di utilizzo della CPU sembra verificarsi quando l'intero elemento '' viene visualizzato fuori dal display. Come hai scritto, non sembra fare la differenza se vedi solo 2px di altezza o tutto il resto. – m90

+0

Questa potrebbe essere la stessa ragione di quando esci dal sito web. Il browser sa che la tela non è in vista e quindi entra in modalità inattiva. Prova a distanziare e tornare indietro 5 minuti più tardi e l'animazione sarà più o meno dove lo hai lasciato. – justanotherhobbyist

Problemi correlati