Animatsiooniline veebiarendus: Jõudlus #1 – Hardware Acceleration

Animatsiooniline veebiarendus: Jõudlus #1 – Hardware Acceleration

Jõudlus on animatsioonilises veebarenduses väga tähtis, sest see omakorda puudutab (animatsioonilise veebiarenduse kuldsõna) kasutajakogemust.

Tänases osas õpetan sulle, kuidas on riistvara seotud jõudlusega ja kuidas seda ära kasutada ning järgmises osas plaanin sulle tutvustada üht kõige tähtsamat tööriista jõudlusest lähtuvalt – Timeline (Chromium tüüpi brauserites) ja Performance (Mozilla tüüpi brauserites).

Kolmandas osas võtame ette sellised toredad asjad nagu service workes.

Millest sõltub üldse animatsioonide jõudlus?

Veebimaailmas sõltub jõudlus väga palju brauseritest ja sellest lähtuvalt käskudest, mida brauserile edasi annad.

Kuna animeerimine käib läbi CSSi omaduste, siis need on ka animatsioonide kvaliteedis väga tähtsad.

Ehk kui soovid saada animatsioone, mis on sujuvad, siis tuleks kasutada omadusi, mis ei ole brauserile eriti “kallid”.

CSSis on põhiliselt kolm tegurit, mida ta mõjutab:

  • asetus – elemendi asetus/positsioon kui ka suurus veebilehel
  • välimus – selle alla mõeldakse elemendi värvust, kuid mitte kuju (värvuse muutmine on kõige ajakulukam ja jõudlust nõudvam)
  • kompositsioon – elemendi suhe teiste elementidega (siinkohal kasutatakse GPUd animeerimiseks – räägin sellest allpool)

Tihtipeale peab muutma neid kõiki tegureid ehk kui muudad asetust, siis muudetakse ka välimust ja kõige lõpuks ka kompositiooni. Seega kui nendest kolmest teguritest saaks mõne kasutamata jätta, siis muutub brauseri töö kergemaks.

Loogiline ju!

Kahjuks aga kasutavad enamus CSSi omadusi kõike neid kolme (nagu näiteks width, height, left jne), mis nõuab brauserilt väga palju tööd.

Õnneks on sellele probleemile olemas lahendus – CSSi teisendused.

Kasuta animeerimiseks CSSi omadusi, mis on brauseri suhtes odavad

transform on üks vähestest CSSi omadustest, mis ei käivita brauseris kõike kolme põhitegurit.

transform ainult käivitab välimuse ja kompositsiooni teguri. Teisi ta tegelikkuses ei mõjuta.

Kui soovid teada, mis protsesse käivitab mingi CSSi omadus, siis CSSTriggers veebilehelt saad seda teada. Jäta meelde, et mida vähem, seda parem!

Ma ei lasku praegu CSSi teisenduste reaalsesse koodi, kuid siit võib leida väikese õpetuse nende kohta.

Mingi näite siiski saad 🙂 ! Vaheta animatsioonide tüüpe ja sa peaksid nägema vahet jõudluses (kui vahet ei näe, siis vajuta nuppu “Edit in JS Fiddle ja jooksuta näidet seal):

Teine võimalus, kuidas jõudlust tõsta on Hardware Acceleration.

Hardware Acceleration

Hardware Acceleration (HA) on otsetõlgituna riistvara kiirendus. See tähendab, et me ei kasuta jõudluse parandamiseks tarkvara, vaid kasutame selleks arvuti enda komponente.

Veebimaailmas kasutatakse HAd just animatsioonide jõudluse parandamiseks. Nimelt kasutavad enamus brausereid 2D animatsioonide jaoks CPUd (protsessorit) ja 3D animatsioonide jaoks GPUd (videokaardi protsessorit).

Õnneks või kahjuks on CPU ja GPU jõudluse vahe massiivne. GPU suudab teha palju rohkem kui CPU.

Riistvara kiirendusega saame me sundida brausereid kasutama videokaarti renderdamiseks. Tegemist on teatud mõttes häkiga, sest me petame brauseri ära muutes näitlikult 2D elemendi “3D” elemendiks.

Nagu häkkidega ikka on, siis on olemas miinused, mida tasuks meeles pidada (räägin nendest allpool).

Iseeneset HAd saab kasutada kahte moodi – CSSiga ja otse animeerides (nt. JavaScriptis).

Tegelikkuses ei ole nendel erilist vahet, sest mõlemad ju kasutavad CSSi omadusi.

Häkk toimib nii tavaarvutitel kui ka nutiseadmetel.

HA koos CSSiga

Põhinipp, nagu ka ennist mainisin, on petta brauserit arvamaks, et tegemist on 3D elemendiga.

3D maailmas on olemas kolm koordinaati: x-koordinaat (vasakult paremale), y-koordinaat (ülevalt alla) ja z-koordinaat (tagaplaanist esiplaanile; põhiliselt elementide “kihid”).

Nüüd kui me tuleme ja muudame ära (või õigemini anname elemendile) z-koordinaadi omaduse, siis arvab brauser koheselt, et tegemist on 3D elemendiga, viib ta eraldi kihile ja siit edasi tegeleb renderdamisega GPU.

Häkk ise on midagi sellist:

.animatable {
   -webkit-transform: translateZ(0);
   -moz-transform: translateZ(0);
   -ms-transform: translateZ(0);
   -o-transform: translateZ(0);
   transform: translateZ(0);
}

Sellisel kujul endasi antud omadused “-prefix-transform” on igale eraldi brauserile omane (kinnitab, et brauser tunneks sellise omaduse ära) – muidu brauserid eiravad neile tundmatuid omadusi. Neid nimetatakse inglise keeles prefix’ideks

Nii on meie 2D element muudetud “ruumiliseks” 😀 ja edasised animatsioonid sellel elemendil (ka siis kui otsustad mitte kasutatada CSSi teisendusi või omadusi, mis ei mõjuta kõiki tegureid) on sujuvamad.

Mõnedes brauserites võib siiksi alles jääda teatud virvendus – selle vältimiseks on olemas loomulikult ka lahendus.

.animatable {
   -webkit-transform: translateZ(0);
   -moz-transform: translateZ(0);
   -ms-transform: translateZ(0);
   -o-transform: translateZ(0);
   transform: translateZ(0);

   -webkit-backface-visibility: hidden;
   -moz-backface-visibility: hidden;
   -ms-backface-visibility: hidden;
   backface-visibility: hidden;

   -webkit-perspective: 1000;
   -moz-perspective: 1000;
   -ms-perspective: 1000;
   perspective: 1000;
}

backface-visibility: hidden – tagakülge “3D” (siinkohal siiski 2D) elemendil ei ole näha. Brauser ei pea tagakülge renderdama.
perspective: 1000 – muudab “3D” (jällegi tegelikult 2D) elemendi perspektiivi suuremaks. Brauser ei pea nii palju tööd tegema. See näide võib asja arusaamisel kasuks tulla.

Nüüd me oleme teinud kõik, et animatsioon oleks võimalikult kiire (kasutades riistvara).

Nagu näed on tegemist päris pika häkiga.

Uuemad brauserid toetavad ka will-change omadust, millega saab asendada transform: translateZ(0);, kuid vanemates brauserites peab siiski tegelema “petmisega”.

will-change omaduse väärtuseks on teised CSSi omadused, mida sa hakkad antud elemendil animeerima. Nii saad häki vabalt kasutada GPU renderdamise eeliseid.”

will-change omadusega näeks meie kood välja selline:

.animatable {
   will-change: transform, opacity; /*Eralda komaga erinevad omadused*/

   -webkit-backface-visibility: hidden;
   -moz-backface-visibility: hidden;
   -ms-backface-visibility: hidden;
   backface-visibility: hidden;

   -webkit-perspective: 1000;
   -moz-perspective: 1000;
   -ms-perspective: 1000;
   perspective: 1000;
}
Kuidas häki kasutada?

Ma soovitaks praegu vähemalt kasutada vanema brauseri moodust, sest ka mõned uuemad brauserid ei toeta will-change omadust (nt. Edge).

Veel mida soovitan on see, et tegemist võiks olla eraldi universaalse klassi stiiliga (siin on ka translateZ(0) moodus parem), et saaksid mis tahes elemendile HA lisada.

Väikene näide/test:

Ära üle pinguta

Ära jumala eest tee midagi sellist:

* {
   -webkit-transform: translateZ(0);
   -moz-transform: translateZ(0);
   -ms-transform: translateZ(0);
   -o-transform: translateZ(0);
   transform: translateZ(0);

   -webkit-backface-visibility: hidden;
   -moz-backface-visibility: hidden;
   -ms-backface-visibility: hidden;
   backface-visibility: hidden;

   -webkit-perspective: 1000;
   -moz-perspective: 1000;
   -ms-perspective: 1000;
   perspective: 1000;
}

Tean enda käest, et see ei too kasu. Kui mind ei usu, siis võid vaadata minu firma kodulehte – seal ma lisasin HA kõikide elementide selektoriga ning jõudlus ei ole seal eriti hea.

Nimelt on sellel imetoredal riistvara kiirendusel ka vead küljes.

Esimene viga on see, et me kasutame ära graafikakaardi mälu. Arvutitel tõesti see erilist midagi ei loe, sest mälu on üsnagi palju, kuid nutiseadmed jäävad tihti hätta.

See ülemine näide, kus ma lisan riistvara kiirenduse kõikidele elementidele dokumendis on jube mälu raiskaja, ka tavalises arvutis.

Põhimõtteliselt mida antud näide teeb on see, et ta viib kõik elemendid eraldi kihile (nagu 3D elemendi).

See kõik on muidu okei, aga mis juhtub siis, kui elemente on 1000 või isegi rohkem?

Nii tekib 1000 eraldi seisvat kihti (oletuslikku 3D elementi).

Nüüd hakkab häkk meie vastu töötama, sest videokaart ei suuda sellist elementide arvu ohjeldada.

Mis on aga lahendus?

Lahendus on väga lihtne – kasuta häkki nii vähe kui võimalik, aga niipalju kui tarvis.

Ma tean, et see ei ole eriti abistav, sest millal on piisavalt palju?

Ma arvan aga, et kui sa kasutad HAd ainult nende elementide peal, mida sa animeerid (oletades, et neid pole üleliia palju), siis see ongi “piisavalt palju”.

Veel mida ma soovitaksin on kasutada riistvara kiirendust koos nende CSSi omadustega, mis ei mõjuta kõiki tegureid. Nõnda on kindel, et sinu veebileht jookseb ilusti.

 

Teine probleem on see, et teatud brauserites võib animatsiooni ajal muutuda tekst häguseks – isegi siis kui animatsiooni lõpus HA eemaldad.

Seda saab parandada JavaScriptiga, kuid see ei ole just kõige parem lahendus, sest siin peab muutma elemendi asetust, mis omakorda muudab suure tõenäosusega elemendi värvust ning lisaks sellele on tegemist meetodiga, millele brauserid ei ole optimeeritud:

var elem = document.getElementById("animate-box");
elem.style.height = (Math.ceil(elem.offsetHeight / 2) * 2) + "px";
elem.style.width = (Math.ceil(elem.offsetWidth / 2) * 2) + "px";

Allikas: Keith Clark – GPU text rendering

HA koos JavaScriptiga

Siin ei ole mitte kui midagi tegelikult juurde seletada, sest kõik, mis ma enne rääkisin kehtib ka siin (JS kasutab ju animeerimseks CSSi omadusi), kuid JS saab meid natukene aidata HA ülekasutamise vastu.

Nimelt, kui me animeerime mingit elementi, siis me saame lisada sellele elemendile juurde transform: translateZ(0), mis muudab elemendi brauseri arvates 3D’ks ja viib ta uuele kihile.

jQuery animatsioonid ei toeta CSSi teisendusi. Selleks tuleb kasutada mingit pluginat/teeki (nt. Transit või velocityJS).

Nii me lisame HA ainult nendele elementidele, mida me reaalselt kasutame.

Mida veel saab öelda JSi plussiks on see, et mõned animatsiooni mootorid/teegid kasutavad riistvara kiirendust automaatselt (ei pea ise midagi tegema), kuid see jällegi sõltub täielikult teegist.

Näiteks velocityJS teotab riistvara kiirendust nutiseadmetel, kuid tavarvutitel peab riistvara kiirenduse manuaalselt lisama.

 

Kahjuks aga on ka HA koos JSiga omal miinused.

Nimelt on väga vastik lisada JSiga kahte viimast häki osa – backface-visibility ja perspective.

Häki kasutamine JSiga

Isiklikult soovitaksin sul kasutada HAd koos CSSiga, kus teed valmis ühe universaalse klassi ja siis seod sellega soovitud elemendid (klassi lisamisel võib ka appi tulla JavaScript).

Kui aga on millegipärast soov lisada HA koos JSiga, siis see näeb välja umbes midagi sellist (kasutan praegu velocityJSi, kuid sõltuvalt teegist, võib see erineda):

$("#animate-box").velocity({
	translateZ: 0
	translateX: "200px"
}, {
	duration: 1000,
	easing: "ease"
});

 

Esimene osa ongi jõudluse kohapealt läbi võetud.

Kui küsimusi tekkis, siis küsi neid julgelt kommenteerides 🙂 !


Senikaua ole tugev ja kohtume juba järgmistes postitustes,

Tähelepanu eest tänades – Oliver Paljak

P.S! Kui oled huvitatud animatsioonilisest veebilehest, siis võta minuga julgelt ühendust AnsiVeebi kodulehel.

Leave a Reply

Your email address will not be published. Required fields are marked *