LeņķaJS: `veidne` pret` veidneUrl`

Pēdējos mēnešos es esmu meklējis dažādus veidus, kā uzlabot izpildlaika veiktspēju milzu SPA, kurā strādāju Domo. Mēs esam panākuši nopietnu progresu, taču ar miljons koda rindām vienā SPA dažas izmaiņas ne vienmēr ir vienkāršas. Viens no mūsu komandas locekļiem veica atklājumu, lai palīdzētu papildināt slīpo ielādi AngularJS projektos, un mēs esam daudz ieguldījuši šajā projektā. Daži dažādi komandas locekļi (Džeisons un Tims) palīdz mums novērtēt laiku, kas nepieciešams mūsu lietotnes pilnīgai inicializēšanai. Mēs arī esam izmantojuši tīmekļa pakotni, lai pilnveidotu versiju, kā arī mainītu dažus mūsu izmantotos modeļus. Apvienojot webpack ar ocLazyload, mēs esam atraduši nopietnu ieguvumu AngularJS projektiem.

Šajā pagājušajā nedēļā es uzņēmos mainīt visas komponentu / direktīvas veidņu deklarācijas un mainīt tās no templateUrl uz šablonu. Tā vietā, lai manuāli pārvietotu visas veidnes no to atsevišķajiem .html failiem uz attiecīgajiem JS failiem, mēs nolēmām izmantot Webpack ielādētāju un pieprasīt veidnes kā iekļautas virknes. Lai to labāk izskaidrotu… ļaujiet man parādīt, ko es domāju. Šis ir AngularJS komponenta paraugs:

Kā redzat, pirmajā piemērā ir komponents, kura ielādēšanai tās veidni izmanto templateUrl. Tas labākajā gadījumā ir problemātisks, SJO. Tas nozīmē, ka jums būs vai nu jāizvieto fails foo / bar / myComponent.html, lai ražošanas programma varētu ielādēt veidnes fragmentu, izmantojot otru tīkla pieprasījumu, lai to iegūtu, VAI tas nozīmē, ka jums būs jāpievieno būve solis, kurā tiks atrasti visi templateUrl gadījumi un ievietotas šīs veidnes AngularJS templateCache. Abiem šiem risinājumiem ir problēmas.

Problēmas ar pirmo ir acīmredzamas: ja visām jūsu ražotajām veidnēm bija nepieciešams atsevišķs tīkla pieprasījums, lai tās iegūtu, tad, lai ielādētu atsevišķu skatu, N tīkla pieprasījumiem būs jāiegūst visi skati, kur N ir komponentu skaits / direktīvas / ngIekļauj jūsu skatījumā.

Otrās problēmas rada tā, ka būvēšanas darbības, lai arī ir parocīgas, visas jūsu veidnes ielādēs jūsu galvenajā tīmekļa paketes paketē. Tas nozīmē, ka pat tad, ja jūs plānojat lazyload komponentu vai visu komponentu sadaļu, to veidnes joprojām tiks ielādētas ar jūsu galveno paketi. Tātad, jūs nevarat pilnībā izmantot priekšrocības, kuras jūs gūstat no slinkās ielādes.

Ņemot vērā daudzos simtus un simtus veidņu, kas mums ir mūsu projektā, neviens no tiem nebija realizējams. Mums bija vajadzīgs kaut kas cits. Mums bija vajadzīgs kaut kas, kas ļautu mums efektīvi ielādēt mūsu veidnes, bez atsevišķiem tīkla pieprasījumiem par katru no tām, vienlaikus ļaujot arī pilnībā lazyload tās pašas veidnes. Tāpēc mēs nolēmām apsvērt iespēju izmantot tīmekļa pakotņu ielādētāju, kas ļautu mums pieprasīt, lai mūsu veidnēs mūsu veidnes būtu HTML / leņķa veidņu inline virknes.

Priekšrocības

Izmantojot Webpack html-loader, lai ielādētu visus .html failus, mēs atklājām, ka mēs varam efektīvi ielādēt mūsu veidnes, vienlaikus ļaujot mums arī pilnībā izmantot slzyload. Lietojot veidni: pieprasīt ('foo / bar / my.html') sintakse, webpack jūsu pieprasījuma paziņojumu aizstāj ar funkciju, kas tiek izsaukta un atgriezta kopā ar veidnes virkni. Tā kā veidne tagad tiek nodrošināta kā html virkne, ja komponentu slinki ielādējat, veidne tiks arī slinki ielādēta. Tas ir tieši tas, kas mums vajadzīgs. Tomēr mēs atklājām vairākus citus ieguvumus, kuru atklāšana pamudināja šo ziņu.

  • Ātrāka komponenta inicializēšana - ja kā veidni izmantojat inline virkni, komponents var sinhronizēt. Izmantojot templateUrl, AngularJS pieprasīs veidni no templateCache. Tā kā veidnē kešatmiņā jau ir veidne kešatmiņā vai, lai to iegūtu, ir jāapmeklē tīkls, veidnes pieprasīšana no kešatmiņas ir process, kas notiek asinhroni. Pat ja veidne jau atrodas kešatmiņā, templateCache atgriezīs jau kešatmiņā saglabāto veidni, izmantojot uz solījumu balstītu zvanu. Tas nozīmē, ka komponents nevar inicializēt tajā pašā notikumu cilpā. Pieprasījums modelCache vienmēr tiks ievietots nākamajā notikumu cilpā, pat labākajā gadījumā. Tas nozīmē, ka komponents var sākt inicializēšanu, pieprasīt tā veidni un pēc tam pabeigt inicializēšanu nākamajā notikuma ciklā. Bet, kad jūs izmantojat iespraustu virkni, komponentam jau ir sagatavota veidne, tāpēc tā sākšanu un pabeigšanu var iniciēt tajā pašā notikumu cilpā. Tas var nešķist nozīmīgs, taču tam bija vairāki negaidīti rezultāti, kas mums bija jākompensē. - Komponenti inicializējas ātrāk - kas izklausās satriecoši, GAISM? Nu, tas ir satriecoši. Tomēr tas nozīmē, ka dažām sastāvdaļām, kurām vienmēr ir definētas ievades vērtības, kad to inicializēšana var tikt pārtraukta, var būt, ka tās pašas vērtības vēl nav. Mums bija vairāku komponentu pārtraukums nenoteiktu ievades saistošo vērtību dēļ. Mums bija jāmaina šie komponenti, lai izmantotu $ watch vai $ onChanges, lai atklātu ievades vērtību atjauninājumu. - Vienības testi darbosies atšķirīgi. Tā kā pārbaudes darbu rakstīšana mainās, kad veicat sinhrono pārbaudi pret asinhrono pārbaudi, šo komponentu pārbaude noteikti var mainīties. Piemēram, Mocha gadījumā, ja jūsu tests ir asinkrāts, jūs savā testā ievadāt izdarīto metodi un saucat to pēc testa veikšanas. Mēs noskaidrojām, ka testi tagad notiek sinhroni, kas nozīmēja, ka vairs nevajadzēja veikt veiktās injekcijas. Tālāk, un tas ir neērts to atzīt, bet mums bija testi, kas tika uzrakstīti sinhroni, tomēr, tā kā veidnes bija asinhronas, šīs pārbaudes nekad nebija sekmīgi izpildītas. Tātad, kad es izdarīju izmaiņas veidņu iespraušanā, šie testi sāka veiksmīgi darboties, un tā vietā, lai tos izturētu, tie KĻŪDA !!!! Sākumā es domāju, ka esmu pārkāpis visus šos testus. Tikai pēc piecām stundām klejojot apkārt, es sapratu, ka šie testi nekad nav izturēti. Tātad mēs tagad esam palielinājuši testu pārklājumu tagad, kad mēs izmantojam inline veidnes.
  • html-loader izmanto html saīsinātāju - šis mazais fakts visā lietotnē uzreiz samazināja mūsu veidņu lielumu par 19%. Tas ir tik izcils, un tas tiešām ir kaut kas tāds, kas mums jau sen būtu jādara. Tas arī parsēja veidnes un palīdzēja mums atrast dažus desmitus veidņu, kurās tajās bija nederīgs HTML. Lietas, piemēram: klase "blah", kur trūka =. Vai atribūts = {{kaut kas}}, kam trūkst pēdiņu ap to visu. Kad es tos laboju, būve atkal strādāja.
  • ng-iekļaušana joprojām tika salauzta - Kamēr komponentu veidnes tagad strādāja, ng-iekļaušanas veidnes tagad tika sadalītas. Mums vajadzēja kaut ko viņiem nākt klajā. Tāpēc mēs izveidojām nelielu pielāgotu iekrāvēju, kas veidni ienes veidnē templateCache. Mūsu iekšējā prakse liek mums nelietot ng-include, taču mums joprojām ir daudz trīs gadu vecu kodu, kas tos satur. Tā vietā, lai atsauktu visu šo apņemšanos, es izmantoju šo jauno ielādētāju un devos uz katru lietotnes sadaļu, kurā ir ng-include un ielādēju šīs sadaļas veidni, kā es parādīju zemāk. Tas nozīmē, ka šajā jaunajā procesā tiek ņemti vērā arī ng-iekļautie.

Lietots JSCodeShift

Es pilnībā iesaku lietot Webpack AngularJS lietotnēm un izmantot html-loader, lai veidnes tiktu ievietotas iekšpusē, kas nozīmē, ka jums būs jāmaina jūsu templateUrl gadījumi uz veidņu gadījumiem. Tā kā tie visi izskatās ļoti atšķirīgi, es nolēmu, ka tas ir ļoti labs JSCodeShift, Facebook projekta, kas ļauj pārmeklēt AST un programmētiski aizstāt visus gadījumus, lietojuma gadījumus. Varat domāt par to, kā atrast un aizstāt steroīdus, ievadīti ar vairākiem steroīdiem. Bija patiešām vienkārši uzrakstīt skriptu, kas atrada un atjaunināja visas šīs templateUrl lietošanas iespējas: 'daži / url / to.html ar veidni: pieprasīt (). Man bija iespēja programmētiski mainīt 90% lietošanas veidu (apmēram 700 faili), un pēdējie 70 man bija jāpabeidz ar roku. Es būtu varējis uzrakstīt kodu, lai pabeigtu tos pārējos 70, bet es sapratu, ka tos varēšu izdarīt vieglāk, nekā mēģinot tos kodēt katru atsevišķi. Īsumā jāpiebilst, ka AST Explorer, lietojot JSCodeShift, ir obligāts nosacījums. Bez tā es nebūtu varējis panākt progresu.

Secinājums

Iegūstiet savas AngularJS lietotnes tīmekļa paketes izveidē un veltiet laiku, lai tās izmantotu, izmantojot HTML ielādētāju, lai ielādētu veidnes. Izmantojiet veidni, nevis templateUrl, un, ja vēl neesat to izdarījis, pārtrauciet lietot ng-include. Un tad, lazyload, lazyload, lazyload! Dažreiz cilvēki atšķir nokavētu iekraušanu un slinku iekraušanu. Es runāju gan par aizkavētu iekraušanu, gan par slinku iekraušanu, kad saku “lazyload”. Šīs ir jūsu labākās izmaiņas, samazinot laiku līdz pirmās nozīmīgās krāsas iegūšanai un saīsinot laiku lietotnes izveidošanai, ar kuru lietotājs var mijiedarboties. Veiksmi. Atpakaļ uz galvas!