Tee JavaScript-sovelluksistasi sujuvampi

Kirjoittaja: Lewis Jackson
Luomispäivä: 5 Saattaa 2021
Päivityspäivä: 15 Saattaa 2024
Anonim
TOP 5 reasons why you should start using Sketch!
Video: TOP 5 reasons why you should start using Sketch!

Tämä artikkeli ilmestyi ensimmäisen kerran .net-lehden numerossa 231 - maailman myydyimmässä verkkosivujen suunnittelijoille ja kehittäjille suunnatussa lehdessä.

Nykyaikaiset verkkosovellukset sisältävät usein reaaliaikaisen animaation ja vuorovaikutteisuuden - kaikkea yksinkertaisista roll-over -efekteistä, Flash-tyyppisistä bannereista ja HTML5: ssä toteutetuista animaatioista pelien loppuunsaattamiseen. JavaScript on nopeampi kuin koskaan nykyisten selainten JIT-kääntäjien ansiosta, mutta yksi ongelma on edelleen: roskien keräys (GC). Tämä voi aiheuttaa taukoja, änkyttämistä ja huonoa suorituskykyä, mikä pilaa sujuvan reaaliaikaisen kokemuksen.

Mutta mitä on roskien keräys? JavaScriptin avulla voit helposti luoda esineitä. Annettua objektia ei kuitenkaan voida poistaa (poisto-operaattoria ei lasketa: se on tarkoitettu objektien ominaisuuksien poistamiseen). Sen sijaan objektit poistetaan automaattisesti, kun niitä ei enää käytetä.

Jos luot 1000 objektia, mutta säilytät viittaukset vain 500: een, selain päättää jossain vaiheessa siivota. 500: een ei viitata missään, joten niitä ei enää käytetä, joten se puhdistaa ne. Jotkin selaimet toteuttavat älykkäitä tekniikoita keräämisen tekemiseksi mahdollisimman nopeasti, kuten sukupolvien keräilijät. Mutta jos luot paljon objekteja JavaScriptiin, ennemmin tai myöhemmin selaimen on siivottava: Suoritus keskeytetään, se viettää jonkin aikaa selvittääkseen, mitä objekteja vielä käytetään, ja sitten loput poistaa.

Tämä voi kestää satoja millisekunteja tai joissakin tapauksissa koko sekunnin tai enemmän. Sujuvan animaation on oltava 60 kuvaa sekunnissa, vain 16 ms / ruutu, joten tämä voi luoda huomattavan tauon. Jos luodaan paljon esineitä, selaimen on ehkä kerättävä useita kertoja sekunnissa, mikä tekee animaatiosta epäselvää. Jos pelaat toimintaohjelmaa HTML5: ssä, muutamat asiat ovat ärsyttävämpiä kuin pomo ilmestyy, lataat energiaa, ajoitat täydellisen liikkeen ... Sitten selain tarttuu hetkeksi, menetät hetkesi ja häviät pelin!

Täydellinen ratkaisu on varmistaa, että kullekin kehykselle ei ole varattu mitään koodiajon aikana. Mutta tämä on yllättävän vaikeaa, koska monet viattoman näköiset lausunnot aiheuttavat roskaa. Yleensä tavoitteena on pitää roskien syntymisnopeus alhaisena, jotta keräykset eivät ole harvinaisia ​​eikä niillä ole paljon puhdistettavaa.

Tärkein tekniikka roskien syntymisen välttämiseksi on esineiden kierrätys. Tämä tarkoittaa, että sen sijaan, että luot paljon esineitä ja heität ne pois, luo muutama objekti käynnistyksen yhteydessä ja käytä niitä uudelleen niin kauan kuin mahdollista. Tämä tarkoittaa myös pysyvien viittausten säilyttämistä esineisiin, jotka olisit muuten heittänyt pois. Välimuistit ovat myös tärkeitä, koska useita esineitä voidaan kerätä kierrätystä varten.


Luotujen objektien lukumäärän minimointi auttaa myös parantamaan JavaScriptin suorituskykyä. Kohdentaminen ja varausten poistaminen vievät aikaa; Näiden poistaminen käyttämällä objekteja uudelleen voi vähentää selaimen tekemän työn kokonaismäärää ja nopeuttaa suoritusta. Jätteiden syntymisen välttämiseksi meidän on ymmärrettävä, mitkä lauseet kohdentavat objekteja - on selvää, että uusi operaattori luo uuden objektin. On kuitenkin joitain yleisiä pikakuvakkeita, jotka luovat myös uusia esineitä, joista sinun tulisi varoa:

{} // sama kuin: new Object () [] // sama kuin: new Array () // luo myös uuden funktion! function () {...}

Älä unohda, että uusia varauksia tehdään edes määritettäessä ominaisuuksia tai elementtejä, mikä on yleistä JavaScriptissä:

// Luo uuden objektin, jolla on ominaisuus {"foo": "bar"} // Luo uuden taulukon, jossa on 3 elementtiä [1, 2, 3] // Luo 4 uutta taulukkoa! [[1, 2], [3, 4 ], [5, 6]]

Vältä kaikkia näitä koodeissa, joita kutsutaan usein, etenkin jokaisessa kehyksessä. Sen sijaan yritä luoda objekti kerran ja viitata siihen pysyvästi. Yksinkertainen muutos on taulukoiden tyhjentäminen, jolloin pituuden asettaminen 0: een on parempi kuin uuden taulukon määrittäminen:


// BAD: roskat vanha matriisi, luo // uusi ja viittaus thatmy_array = []; // PAREMPI: käytä samaa taulukkoa objectmy_array.length = 0;

Toiminnot voivat myös saada sinut kiinni. Saatat tietää, että toiminnot toimivat myös kuin JavaScript-objektit - mutta luulitko, että ne lasketaan myös roskiksi? Suurin osa toiminnoista ei ole ongelma, koska luot ja määrität ne vain käynnistyksen yhteydessä ja käytät niitä uudelleen. Toiminnot, jotka palauttavat muita toimintoja (kuten sulkemisissa), voivat kuitenkin olla enemmän ongelmia kuin luulet. Harkitse seuraavaa esimerkkiä requestAnimationFrame kutsua pelin rasti-toiminto objektiin (toimittajakohtaiset laajennukset ja kiertotavat on jätetty selvyyden vuoksi):

// BAD: luo kokonaan uusi funktio // (joka on roskat kerätty) // ja kutsu se seuraavaa framerequestAnimationFrame ((function (self) {return function () {self.tick ();};}) (tämä )); // PAREMPI: käytä samaa ruututoimintoa uudelleen! // Käynnistyksen yhteydessä: this.tick_function = (function (self) {return function () {self.tick ();};}) (this); / / Kun pyydetään seuraavaa puhelua: requestAnimationFrame (this.tick_function);

Ei ole kuullut requestAnimationFrame ennen? Etsi se, se on parempi kuin setInterval tai setTimeout animaatioihin!

Joka tapauksessa, huomaa, kuinka ensimmäinen esimerkki luo uuden toiminnon kutsuakseen jokaisen rasti. Toinen luo yhden käynnistyksen yhteydessä ja käyttää sitä uudelleen, mikä välttää funktion heittämisen jokaiseen kehykseen.

Samaa voidaan soveltaa esineisiin. Voit käyttää objektia uudelleen poistamalla sen ominaisuudet ja lisäämällä ne uudestaan ​​tyhjästä uuden objektin määrittämisen sijaan. Tämä ei kuitenkaan ole yleensä hyvä idea. Nykyaikaiset selaimet optimoivat esineiden pysymisen ennallaan. Ominaisuuksien poistaminen aiheuttaa useiden JavaScript-moottorien optimoinnin poistamisen ja hidastumisen.

Sinun tulisi ehdottomasti välttää ominaisuuksien poistamista yleensä. Se on kuitenkin kompromissi - jos ominaisuuksien poistaminen säästää tarpeeksi roskaa taukojen vähentämiseksi, ja se on sen arvoista, koska pienempi suoritusnopeus kyseisen objektin käytössä on, voit ehkä päästä eroon siitä. Muista kuitenkin, että aina kun mahdollista, on parempi käyttää objektia, jolla on samat ominaisuudet, eikä poistaa mitään.


Siirtyminen eteenpäin asioista tulee hieman vaikeammiksi. Monet JavaScript-kirjastotoiminnot palauttavat uusia objekteja, mikä voi vaikeuttaa allokointien välttämistä. Esimerkiksi Taulukko object's slice -funktio palauttaa uuden taulukon vanhan taulukon osan perusteella. Jos soitat viipaleeseen, kohdistaminen suoritetaan, eikä siinä voi tehdä muuta kuin välttää sen kutsumista. Voit myös kirjoittaa jakamisvapaan version JavaScriptiin, mutta saatat päätyä keksimään pyörän uudelleen ja ottamaan käyttöön paljon yhteisiä JavaScript-toimintoja. Se saattaa kuitenkin olla syytä harkita roskien luomisen kuumissa kohteissa.

Kuten aina, Mozilla Developer Network (MDN) on hyvä paikka etsiä JavaScript-kirjastotoimintoja. Esimerkiksi MDN-dokumentaatio Array.leike toteaa, ettäviipale ei muuta alkuperäistä taulukkoa, mutta palauttaa uuden yhden tason syvän kopion. Tämä on vihjeemme siitä, että funktio palauttaa kopion (uuden taulukon) alkuperäisen muokkaamisen sijaan; siksi meidän tulisi välttää sitä minimoimalla roskien syntyminen. Kun etsit kehyskoodikoodin polun muita toimintoja, voit myös selvittää, luovatko ne uusia objekteja vai muokkaavatko ne paikan päällä. Ne voi olla helppo sekoittaa. Jos mahdollista, objektinluontitoimintojen korvaaminen toiminnoilla, jotka muuttavat objektia paikallaan, voi auttaa vähentämään roskien syntymistä. Harkitse alla olevaa esimerkkiä:

// Tarkoitus: pienennä matriisi elementeiksi // 1, 2 ja 3.// BAD: kutsuva siivu: uusi taulukko luodaan // ja vanha on garbagedarr = arr.slice (1, 4); // PAREMPI: asetettu pituus kohtaan 4, sitten shift // (ensimmäisen elementin poistaminen) // Ei luo uusia objekteja! arr.length = 4; arr.shift ();

Välimuistit voivat myös auttaa sinua kierrättämään paljon esineitä. Esimerkiksi hiukkasvaikutus voi tallentaa joukon hiukkasesineitä. Kun hiukkaset tuhoutuvat, voit vain poistaa ne ryhmästä, josta ne tulevat roskiksi ja puhdistetaan myöhemmin. Älykkäämpi valinta on kierrätys: niiden siirtäminen "kuolleiden hiukkasten ryhmään".

Uusia hiukkasia luodessa, jos ”kuolleiden hiukkasten ryhmässä” on esineitä, pop() kohteen ja palauta se alkuperäiseen tilaansa, siirrä se sitten takaisin aktiivisten hiukkasten ryhmään. Jos ”kuolleiden hiukkasten ryhmä” on tyhjä, sinulla ei ole muuta vaihtoehtoa kuin luoda uusi Hiukkanen(), mutta se on OK; sinun on kuitenkin luotava uudet hiukkaset käynnistyksen yhteydessä (kun taulukko on alun perin tyhjä), ja siitä lähtien ne kierrätetään.

Samanlaisia ​​periaatteita voidaan soveltaa kaikkialla JavaScriptissä. Sinulla voi olla esimerkiksi pino esineitä, jotka on toteutettu työntämällä ja ponnahtamalla matriisiin. Jos taulukosta ponnahtaminen viettäisi objektin, voit harkita sen tallentamista välimuistiin. Voit käyttää myös kokonaislukua, joka osoittaa pinon "ylimpään hakemistoon", ja lisätä ja vähentää sitä sen sijaan, että työntäisit ja avaisit, kierrätät esineitä mennäsi. Pinot voivat olla myös tärkeä tapa kiertää uusien objektien siirtäminen rekursiivisissa funktioissa, vaikka se onkin hyödyllistä kuin {} syntaksia, se voi silti luoda paljon roskaa.

Jotkut JavaScriptin GC-suorituskyvyn pahimmista rikkomuksista ovat vektoriobjekteja (kuten objekti, joka sisältää x- ja y-koordinaatit); Box2D-fysiikan JS-toteutukset kärsivät usein tästä ongelmasta. Tällaisten kohteiden ympärille suunnitellut kirjastot voivat luoda tuhansia vektoriobjekteja sekunnissa, usein ilman mahdollisuutta kierrättää niitä, tai vaatia erityisiä puheluja niiden "vapauttamiseksi", mikä voi olla hankalaa päästä tarkalleen oikeisiin paikkoihin.

Tällaisilla kirjastoilla tehdyt sovellukset näyttävät usein pahimmat roskien keräystaukot. On paljon parempi, että toiminnot toimivat kullakin koordinaatilla erikseen - kuten getX () ja getY (), jotka palauttavat yksinkertaisia ​​numeroita eikä getPosition (), joka palauttaa uuden vektori2 (…). Kun päätät kirjastojen välillä, parhaan suorituskyvyn saavuttamiseksi haluat todennäköisesti välttää sellaisia ​​vektoriobjekteja käyttäviä. Vektoriobjektit ovat todellakin käteviä, ja ne voivat tehdä koodistasi siistimmän ja yksinkertaisemman, mutta JavaScript-kielen muotoilu vaikeuttaa niiden käyttöä luomatta suuria määriä roskia - mikä tekee pelistäsi tai animaatiosta hienomman!

Joten muutosten tekeminen GC: n yleiskustannusten vähentämiseksi voi valitettavasti tehdä koodistasi monimutkaisemman ja vaikeasti seurattavan. Mutta huolella on täysin mahdollista luoda reaaliaikainen JavaScript, joka tekee peleistä, tehosteista tai animaatioista sujuvamman ja reagoivamman kuin muut.

Julkaisut
Paras ilmainen logosuunnittelija: paras maksettu ja ilmainen logosuunnittelijaohjelmisto
Lue Lisää

Paras ilmainen logosuunnittelija: paras maksettu ja ilmainen logosuunnittelijaohjelmisto

Jo ku para ilmainen logo uunnittelija tai premium-logo uunnittelijaohjelmi to opii täydelli e ti logon uunnittelu a. Jo valit et yhden ilmai i ta logo uunnittelutyökalui ta, voit luoda jotai...
10 adventtikalenteria verkkosuunnittelijoille ja kehittäjille
Lue Lisää

10 adventtikalenteria verkkosuunnittelijoille ja kehittäjille

e on kau i olla nörtti. Muutaman viime vuoden aikana web- uunnittelijoiden ja kehittäjien virtuaali et adventtikalenterit ovat tulleet yhä uo itummik i. On monia, jotka ovat tulleet ja...
Verkkosuunnittelijan aloitustyökalupakki
Lue Lisää

Verkkosuunnittelijan aloitustyökalupakki

Verkon alkuaikoina uunnittelijan työkalupakki oli heikolla puolella. Muut kuin uurten pelaajien tarjoamat verkko uunnittelutyökalut, vaihtoehdot olivat melko rajalli et. Nyt on työkalu,...