Učitavanje JS modula na HTTP\2 način

Vladimir Jovanović
Vladimir Jovanović
5 min readOct 23, 2017

Jedan od najvećih nedostataka HTTP\1.1 protokola je to što omogućava sinhrono učitavanje samo dva resursa u isto vreme, čime produžava vreme učitavanja sajta ili aplikacije čak i sa velikim brzinama Internet protoka. Novi protokol HTTP\2, koji sve više uzima zamaha, taj problem efikasno rešava.

Teoretski je sada moguće učitati neograničen broj resursa u isto vreme, ali je praksa pokazala da je taj broj ograničen hardverskim mogućnostima i podešavanjima servera. Taj broj se u realnosti kreće između 50 do 100 resursa koji se učitavaju sinhrono.

Paketi skripti

Najveći nedostatak starog protokola je u tome što je dovodio do blokiranja učitavanja stranica. Skripte su morale da se učitavaju u grupama od po dve, što je vodilo u loše korisničko iskustvo. Problem je rešen na taj način što su se skripte povezivale u jedan paket (eng. Bundle) koji se potom sam učitavao na HTML strani. Tu je automatski bio rešen problem i oko redosleda učitavanja skripti.

Ovaj način treba shvatiti kao privremeno rešenje kojim su se prevazilazila ograničenja protokola. Od najpoznatijih skripti za pravljenje tih paketa bih izdvojio Browserify i Webpack.

Koji su nedostaci ovog rešenja?

  • Izmenama makar jedne skripte unutar paketa potrebno je praviti novi paket
  • Keširanje sadržaja nije efikasno jer se posle svake izmene učitava nov paket, čime se značajno produžava inicijalno učitavanje sajta.
  • Individualne skripte, koje se retko ili nikad ne menjaju, ne mogu ostati keširane
  • Paketi mogu da narastu do nerazumnih mera
  • Deljenjem paketa po stranama se opet stvara problem sa keširanjem sadržaja, jer pregledači (eng. Browser) za svaku stranu učitavaju novi paket i ne mogu da koriste keširan sadržaj.

U praksi sam sretao rešenja gde su paketi narasli i do 2MB uz minificiran sadržaj, što je po meni apsolutno nedopustivo kada se u obzir uzmu performanse i korisničko iskustvo. Problem je i što se većina tog koda uglavnom ne izvršava na stranici na kojoj je učitan.

Većina paketa ima preko 60% koda koji se ne izvršava na stranici na kojoj je učitan

Amazon je u svom istraživanju došao do toga da se za svakih 100ms produženog učitavanja stranice, prodaja smanjuje za 1%. To je 10% manje prodaje na svaku dodatnu sekundu učitavanja stranice!

Novo rešenje za stare probleme

Dolaskom HTTP\2 protkola je konačno rešen glavni problem zbog koga su paketi skripti i nastali. Sada možemo bez problema učitavati veliki broj skripti na strani, a već dugo vremena imamo i alatke sa kojima to možemo učiniti na pravilan način.

RequireJS
Prvi pogram koji se bavio dinamičkim učitavanjem skripti je bio RequireJS i napravljen je još davne 2009. godine. Sa njim ste mogli da definišete uzajamne povezanosti skripti i potom ih učitavate kao AMD module.

Ceo princip dinamičkog učitavanja međusobno povezanih skripti radi prilično dobro na HTTP\2 i bez pravljenja paketa. Skripte su ostajale keširane u pregledačima i brzina učitavanja stranica je značajno povećana, što sam potvrdio i u praksi kroz svoje projekte.

Problem sa RequireJS je to što je napravljen pre nego što je u pregledačima stvoren mehanizam za predučitavanje skripti. O tome možete više da pročitate na sledećem linku:

U praksi to može da izgleda ovako:

Skripta A zahteva Skriptu B koja zahteva Skriptu C
RequireJS će učitati prvo A, pa B, pa C, rešiće problem međusobne povezanosti i onda će ih primeniti na stranici ispravnim redosledom. Problem je što će ih učitavati sa određenim pauzama koje definitivno utiču na vreme učitavanja sajta. Što je dubina međusobnih povezanosti veća, to će se praviti veće pauze u preuzimanju resursa sa servera. RequireJS nema ugrađen mehanizam za predučitavanje skripti.

To znači da je RequireJS moguće koristiti i danas za fantastične performanse na HTTP\2 serverima, ali da performanse opadaju sa sve većom međusobnom povezanošću skripti.

SystemJS
SystemJS predstavlja modernije rešenje koje poseduje mehanizme za rad sa HTTP\2 protokolom. Za razliku od RequireJS-a, SystemJS može da učitava i različite tipove modula. Poseduje podršku za stari AMD sistem, ali i za CommonJS i ES module. Za poslednje je potrebno učitati i transpiler da bi radili kako treba.

Ono što je najvažnije, kroz SystemJS je moguće definisati unapred međusobnu povezanost skripti koje će potom u istom prolazu biti učitane na stranicu. To se rešava kroz metod DepCache.

U ovom slučaju će povezane skripte biti učitane od jednom preko rel=”preload” metode, a biće pozvane čim budu zatražene od neke druge skripte na stranici.

Podrška za “preload” je u trenutku pisanja ovog teksta prilično dobra, a u vremenu koje dolazi će biti sve bolja.

Na ovaj način je eliminisan i poslednji nedostatak koji je RequireJS imao i tako potpuno eliminisana potreba za pravljenjem paketa skripti i na velikim sajtovima. Povratili smo mogućnost da učitavamo samo one skripte koje su nam potrebne na datim stranicama, da uspešno keširamo naše resurse, lakše organizujemo naše radne procese i samim tim povećamo performanse sajtova i aplikacija. Sve to se opet pozitivno odražava i na poslovanje, profit i korisničko iskustvo posetilaca.

Savet za dalje

Korišćenje paketa skripti je stara navika koja se zadržala od još od kada je pre desetak godina front-end razvoj počeo da se usložnjava. Tada je proces pakovanja prevazilazio ograničenja tadašnje tehnologije, što je danas već uveliko rešeno. Zbog toga više ne postoje valjani razlozi da skripte ne učitavamo na ovaj moderan način.

Ukoliko vam se ovaj članak svideo, a koristi vam u vašem dizajnu i kodiranju, posetite Bitersen stranicu na Facebook mreži jer ću tamo kačiti i ostala rešenja iz veb dizajna do kojih sam sam došao.

Za zanimljivosti iz veb dizajna, programiranja i IT-a, posetite moju stranicu posvećenu tome — Web design | Vladimir Jovanović.

Čitamo se ;)

Vladimir Jovanović
Web designer & developer

--

--