AngularJS: `sniðmát` vs` sniðmátUrl`

Undanfarna mánuði hef ég verið að skoða ýmsar leiðir til að bæta afköst tímabilsins á risastóru SPA sem ég vinn á Domo. Við höfum náð nokkrum árangri en með milljón lína af kóða í einum SPA eru sumar breytingarnar ekki alltaf auðveldar. Einn af liðsmönnum okkar gerði uppgötvunina til að hjálpa til við að bæta lazyload í AngularJS verkefnum og við höfum fjárfest mikið í þessu. Nokkrir ólíkir liðsmenn (Jason og Tim) leggja áherslu á að hjálpa okkur að mæla þann tíma sem það tekur appið okkar að frumstilla fullkomlega. Við höfum einnig notað webpack til að straumlínulaga bygginguna, svo og breyta nokkrum mynstrum sem við notum. Þegar vefpakkinn er sameinaður ocLazyload höfum við fundið verulegan árangur fyrir AngularJS verkefni.

Í þessari síðustu viku tók ég að mér að breyta öllum yfirlýsingum sniðmáts íhluta / tilskipana og breyta þeim úr templateUrl í sniðmát. Í stað þess að færa öll sniðmátin handvirkt úr aðskildum .html skrám sínum í JS skrárnar sínar, ákváðum við að nota vefpokaprófar og krefjumst sniðmátanna sem innbyggða strengja. Til þess að útskýra það betur ... leyfðu mér að sýna þér hvað ég meina. Eftirfarandi er sýnishorn af AngularJS íhluti:

Eins og þú sérð er í fyrsta dæminu hluti sem notar sniðmátUrl til að hlaða sniðmátið. Þetta er í besta falli erfitt, IMO. Það þýðir að þú verður annað hvort að nota foo / bar / myComponent.html skrána til framleiðslu svo framleiðsla appið þitt geti hlaðið sniðmátsbrotið í gegnum aðra netbeiðni til að fá hana, EÐA það þýðir að þú þarft að bæta við build skref sem finnur öll tilvik templateUrl og færir þau sniðmát inn í AngularJS templateCache. Báðar þessar lausnir eiga í vandræðum.

Vandamálin við það fyrsta eru augljós: ef öll sniðmát þín í framleiðslu þurftu sérstaka beiðni um net til að fá þau, þá myndi N-beiðnir þurfa að hlaða hverja eina skoðun til að fá öll sjónarmið, þar sem N er fjöldi íhluta / tilskipanir / ngTalar til þín.

Vandamálin við annað eru þau að smíði skrefanna, þó að þau séu frábær handhæg, mun hlaða öll sniðmátin í aðalvefpakkann þinn. Þetta þýðir að jafnvel þegar þú ætlar að hlaða niður hluta, eða heilan hluta íhluta, þá verða sniðmát þeirra samt hlaðin með aðalbúntinn þinn. Svo þú getur ekki nýtt þér ávinninginn sem þú færð af lazyloading til fulls.

Miðað við mörg hundruð og hundruð sniðmátanna sem við höfum í verkefninu okkar, var hvorugt þeirra framkvæmanlegt. Okkur vantaði eitthvað annað. Okkur vantaði eitthvað sem myndi gera okkur kleift að hlaða sniðmátin okkar á skilvirkan hátt, án sérstakra beiðna netkerfis fyrir hvern og einn, en jafnframt að leyfa okkur að hlaða sömu sniðmát að fullu. Við ákváðum því að skoða vefpokastillingu sem gerir okkur kleift að krefjast sniðmátanna í íhlutina okkar sem línur strengja af HTML / hyrndum sniðmátum.

Ávinningurinn

Með því að nota webpack html-hleðslutækið til að hlaða allar .html skrár komumst við að því að okkur tókst að hlaða sniðmát okkar á skilvirkan hátt, en einnig leyfa okkur að nýta lazyloadinguna að fullu. Þegar þú notar sniðmátið: þurfa ('foo / bar / my.html') setningafræði, kemur webpack í stað kröfuyfirlýsingarinnar með aðgerð sem er kölluð og skilað með strengnum fyrir sniðmátið. Þar sem sniðmát er nú til staðar sem HTML strengur, ef þú lazyload hluti, mun sniðmátið einnig vera lazyloaded. Þetta er nákvæmlega það sem við þurftum. Við uppgötvuðum þó nokkra aðra kosti, en uppgötvunin varð til þess að þessi færsla var gerð.

  • Hraðari upphafsíhluti - Þegar þú notar inline streng sem sniðmát getur íhluturinn byrjað samstilltur. Með því að nota templateUrl mun AngularJS biðja um sniðmátið frá templateCache. Þar sem sniðmát skyndiminni getur þegar verið með sniðmátið í skyndiminni, eða gæti þurft að fara yfir netið til að fá það, að biðja um sniðmát úr skyndiminni er ferli sem gerist ósamstilltur. Jafnvel ef sniðmátið er þegar í skyndiminni mun templateCache skila sniðmátinu sem þegar er búið til í skyndiminni í gegnum loforðssímtal. Þetta þýðir að íhlutinn getur ekki byrjað í sömu atburðarás. Beiðnin til templateCache verður alltaf sett á næsta atburðarás, jafnvel í bestu tilfellum. Þetta þýðir að íhluturinn getur byrjað að frumstilla, beðið um sniðmát og klárað síðan frumstilling í næsta atburðarás. En þegar þú notar inline streng, þá er hluti þess þegar sniðmát tilbúið, þannig að það getur byrjað og lokað upphafsstillingu í sömu atburðarás. Þetta virðist kannski ekki marktækt en það hafði nokkrar óvæntar niðurstöður sem við urðum að bæta fyrir.
    - Íhlutir frumstilla hraðar - sem hljómar ógnvekjandi, AIR? Jæja, það er æðislegt. En það þýðir að sumir hlutar þinna sem hafa alltaf haft inntaksgildin skilgreindir þegar frumstillingar þeirra geta brotnað, valda því að sömu gildi eru kannski ekki til ennþá. Við vorum með nokkra hluta brot, vegna óskilgreindra bindisgilda. Við urðum að breyta þessum íhlutum til að nota $ watch eða $ onChanges til að greina uppfærsluna á inntaksgildunum.
    - Einingapróf munu keyra á annan hátt - Þar sem skrifpróf breytast þegar þú ert að gera samstillt próf vs ósamstillt próf, prófið fyrir þessa íhluti gæti örugglega breyst. Til dæmis, í Mokka, ef prófið þitt er ósamstillt, sprautarðu gerð aðferðinni í prófið þitt og hringir í það þegar prófið er gert. Við fundum að prófin gengu nú samstillt, sem þýddi að þörfin á að sprauta var ekki lengur nauðsynleg. Ennfremur, og það er vandræðalegt að viðurkenna þetta, en við vorum með próf sem voru skrifuð samstillt, þó að sniðmátin væru ósamstillt, þau próf náðu ALDREI að klára. Svo þegar ég framdi breytingarnar til að flokka sniðmátin fóru þessi próf að keyra með góðum árangri, og í stað þess að fara framhjá, þá mistókust þau !!!! Í fyrstu hélt ég að ég hefði brotið öll þessi próf. Það var ekki fyrr en eftir 5 klukkustunda pælingu að ég áttaði mig á því að þessi próf voru aldrei að standast. Þannig að við höfum nú reyndar aukið umfjöllun um próf núna þegar við notum inline sniðmát.
  • html-hleðslutæki notar html minifier - Þessi litla staðreynd minnkaði umsvifalaust stærð sniðmátanna okkar um 19% í öllu forritinu. Þetta er svo framúrskarandi og er í raun eitthvað sem við hefðum átt að gera í langan tíma. Það parar einnig sniðmátunum og hjálpaði okkur að finna nokkra tugi sniðmáta sem voru með ógilt HTML í þeim. Hlutir eins og: flokkur „bla“, þar sem = vantaði. Eða eiginleiki = {{eitthvað}}, sem vantar tilvitnanir í það allt. Þegar ég lagaði þær virkaði byggingin aftur.
  • ng-include voru enn brotin - Þó að sniðmát íhluta væri nú að virka voru ng-include's nú brotin. Við þurftum að koma með eitthvað fyrir þá. Svo við smíðuðum lítinn sérsniðinn hleðslutæki sem mun færa sniðmátið inn í templateCache. Innri starfshættir okkar segja okkur að nota ekki ng-include, en við höfum samt fullt af 3+ ára kóða sem inniheldur þær. Svo, frekar en refactor allt þetta í þessum skuldbindingum, notaði ég þennan nýja hleðslutæki og fór í hvern hluta forritsins sem er með ng-include og hlaðinn sniðmátinu fyrir þann hluta, eins og ég hef sýnt hér að neðan. Þetta þýðir að ng-innifalið er einnig gætt í þessu nýja ferli.

Notað JSCodeShift

Ég mæli fullkomlega með því að nota webpack fyrir AngularJS forrit og nota html-hleðslutæki til að koma sniðmátunum í röð, sem þýðir að þú þarft að breyta sniðmátUrl tilvikum í sniðmátsdæmi. Þar sem allir líta mjög misjafnlega út ákvað ég að þetta væri mjög gott notkunaratriði fyrir JSCodeShift, verkefni frá Facebook sem gerir þér kleift að skríða AST og skipta forritlega út fyrir öll tilvik fyrir þig. Þú getur hugsað um það sem Find & Replace On Steroids, Injected w / More Steroids. Það var í raun einfalt að skrifa handritið sem fann og uppfærði alla þessa notkun sniðmátsUrl: ‘sumir / url / to.html með sniðmát: krefjast (). Mér tókst að breyta 90% af notkunum dagskrárgerð (um 700 skrár) og ég varð að klára síðustu 70 fyrir höndina. Ég hefði getað skrifað kóðann til að klára þessar 70 aðrar, en ég reiknaði með að ég gæti gert þetta auðveldara fyrir hönd en með því að reyna að kóða þá hver fyrir sig. AST er fljótlegt að AST Explorer er alger nauðsyn þegar JSCodeShift er notað. Án þess hefði ég ekki getað náð framförum.

Niðurstaða

Fáðu AngularJS forritin þín á vefpakkaframleiðslu og settu þér tíma til að koma þeim yfir í að nota html-hlaða til að hlaða sniðmátin þín. Notaðu sniðmát í stað sniðmátsUrl, og ef þú hefur ekki gert það skaltu hætta að nota ng-include. Og svo, lazyload, lazyload, lazyload! Stundum greina menn á milli seinkaðrar fermingar og latrar fermingar. Ég er að vísa í bæði seinkaða fermingu og lata fermingu þegar ég segi „lazyload“. Það er besta breytingin þín að minnka tímann í First Meaningful Paint og minnka tímann til að eiga app sem notandinn getur haft samskipti við. Gangi þér vel. Aftur á höfðinu!